2015-12-03 5 views
2

У меня есть старый проект, который я переношу на Win 10. Нам нужно поддерживать совместимость с Windows XP, и мне не удалось получить преобразованные проекты в даже зарегистрироваться в XP. Чтобы понять, что необходимо (после многих недель поиска как переполнения стека, так и MSDN), я попытался создать Dll на основе ATL с помощью VS 2015 - и это не сработает. Прежде чем идти дальше, позвольте мне убрать несколько вещей:Visual Studio 2015 не может создать ATL Dll, которая успешно регистрируется в Windows XP

1) Да, я установил VS 2015 с поддержкой C++ для XP. 2) Да, я поставил платформу набор инструментов для XP 3) Да, я установил VS 2015 x86 распространяемый пакет на XP целевого

Если я просто пройти через мастер ATL проекта и остановки перед добавлением COM интерфейсов, Dll успешно регистрируется на XP. Если я добавлю интерфейс без каких-либо методов, regsvr32 завершится с кодом возврата 0xc0000005. Если я добавлю метод к интерфейсу и поставлю реализацию, он по-прежнему терпит неудачу таким же образом.

Если вы можете поставить недостающую деталь, я был бы благодарен. Процесс я прохожу генерировать минимальный Dll занимает около 5 минут усилий, вот мои шаги (настройки выбраны, чтобы наилучшим образом аппроксимировать Dll я хочу порт):

Необходимые среды:

Вам нужно будет система Win 10 с установленной версией Visual Studio 2015 с поддержкой XP (вы получите ошибки сборки, если опция поддержки XP C++ не была проверена во время установки, она не является стандартным вариантом) и

Система Windows XP с VS 2015 x86, распространяемый (доступно здесь: https://www.microsoft.com/en-us/download/details.aspx?id=48145)

O pen VS 2015, выберите File/New/New Project ...

• Из окна Installed/Templates/Visual C++/Windows в левой части диалогового окна выберите «ATL» в качестве фильтра типа проекта, • Выберите «Проект ATL» в качестве типа проекта из списка шаблонов в центре диалога. • Выберите «.NET Framework 3.5» в качестве платформы .NET Framework из раскрывающегося списка в верхней части диалогового окна • Назовите проект «DllHoopty», • Выберите опцию «Создать каталог для решения» в правом нижнем углу диалог. • Нажмите «ОК», чтобы запустить мастер проекта.

При появлении мастера проекта текущие настройки проекта должны быть «Библиотека динамических ссылок».

• Нажмите «Next», НЕ «Готово»

На странице «Настройки приложения»:

• Выберите «Разрешить слияние прокси-кода/заглушки», • Deselect «Безопасность Жизненный цикл развития (SDL). • Оставьте «Поддержка MFC» и «Поддержка COM + 1.0» непроверенной. • Нажмите «Готово», чтобы создать проект &.

Когда проект/решение было создано:

• Выберите «Release» в конфигурации, и «x86» в качестве платформы. • Щелкните правой кнопкой мыши по проекту DllHoopty и выберите «Свойства». • В диалоговом окне свойств убедитесь, что Конфигурация и платформа являются «Release» и «Win32», соответственно • Если он еще не выбран, перейдите на панель «Свойства конфигурации/Общие» • Измените «Набор инструментов платформы» «На» Visual Studio 2015 - Windows XP (v140_xp) » • Нажмите« ОК », чтобы сохранить изменения и закрыть панель свойств.

Если вы остановитесь здесь и построите решение, созданная dll будет УСПЕШНО зарегистрироваться.

Щелкните правой кнопкой мыши по проекту DllHoopty и выберите «Add/Class ...» из всплывающего меню, чтобы открыть диалог Add Class. • Выберите «Установленный/Visual C++/ATL» из дерева и «ATL Simple Object "Из списка шаблонов • Нажмите« Добавить », чтобы запустить мастер простых объектов ATL.

• На странице «Добро пожаловать на сайт ATL Simple Object Wizard» дайте объекту «Краткое имя» Hoopty. Это приведет к заполнению всех остальных полей. • Нажмите «Далее». • Нажмите «Next» на «Тип файла Handler Опции»

На странице «Параметры»: • Выберите «Single», как потоковая модель, • Выберите «Нет» в качестве опции «Aggregation», • Выберите «Пользовательский» в качестве опции «Интерфейс». • Оставьте поле «Автоматически совместимое» в разделе «Пользовательский» непроверенным. • Все флажки «Поддержка» должны быть сняты.
• Нажмите «Готово»

В этот момент и за пределами любой произведенной DLL не будет зарегистрирован сообщение «Ошибка DllRegisterServer в DllHoopty.dll. Код возврата был 0xc0000005 «

Открыть файл« DllHoopty.idl », • добавить« HRESULT Wub(); »к« интерфейсу IHoopty », например. изменить его следующим образом:

interface IHoopty : IUnknown{ 
    HRESULT Wub(); 
}; 

Открыть «Hoopty.h» • Добавить

STDMETHOD(Wub)(); 

для общественности: раздел в конце объявления класса CHoopty

Открыть «Hoopty. каст» • добавить:

STDMETHODIMP CHoopty::Wub() 
{ 
    return S_OK; 
} 

Создание проекта (изготовление сюр e Release/x86 - это выбранная конфигурация &)

• Переместите «DllHoopty.dll» на локальный жесткий диск (не общая папка, если вы используете виртуальные машины с VirtualBox, как я) на машине Win XP с Установлен дистрибутив C++.

На машине XP: • Вызовите командную строку, • Перейдите к местоположению DllHoopty.dll, • запустить «regsvr32 DllHoopty.dll».

Если мое предположение верно, то вы получите диалоговое окно с сообщением об ошибке:

«DllRegisterServer в DllHoopty.dll не удалось.Код возврата был: 0xc0000005 «

Я пробовал много и много вещей: Добавляет определения для WINVER 0x0501, _WIN32_WINNT 0x0501, _ATL_XP_TARGETING и многие другие, о которых я забыл. Ничего не меняет результат.

+0

* Процесс, который я получаю для создания минимальной Dll, занимает около 5 минут усилий * - Удачи в поиске кого-то со временем, чтобы настроить или иметь все эти предпосылки. – PaulMcKenzie

ответ

4
  1. Свяжите CRT статически - в Config Свойства/C/C++/Генерация кода/Runtime библиотеки выберите без DLL многопоточный вариант, например /MT в сборке выпуска.

  2. Добавить /Zc:threadSafeInit- (n.b. trailing - является частью коммутатора) в параметры компилятора в разделе «Свойства конфигурации»/C/C++/Командная строка/Дополнительные параметры.

Обходное решение № 2 исходит из открытого футляра https://connect.microsoft.com/VisualStudio/feedback/details/1907257.

Windows Server 2003 и Windows XP имеют проблемы с динамической загрузкой DLL (через LoadLibrary), который использует локальную память потока, который является то, что использовать поточно-статику внутри, чтобы обеспечить эффективное выполнение, когда статические локальными уже инициализируется. Поскольку эти системы не поддерживаются, крайне маловероятно, чтобы патч был создан для этих систем, чтобы добавить эту поддержку, как это присутствует в Vista и более новых ОС, и мы неохотно наказываем производительность в операциях поддержки, чтобы обеспечить это функциональность для старых внекорпоративных.

Чтобы обойти проблему, вы можете использовать/Zc: threadSafeInit-, чтобы отключить код инициализации с потоком, и это позволит избежать локальной переменной потока. Конечно, при этом код инициализации возвращается в режим VS2013 и не является потокобезопасным, поэтому этот параметр является жизнеспособным, если вы не полагаетесь на безопасность потоков локальной статистики.

+0

Отличный ответ, это работает. –

+0

Спасибо! Ты спас день! – Devgrapher

+0

@dvix Ты спас меня после 8 часов расследования. Я люблю тебя. Огромное спасибо!! 2) исправил это для меня. – tmighty

 Смежные вопросы

  • Нет связанных вопросов^_^