2015-12-03 45 views
2

我有一個遺留項目,我正在移植到Win 10.我們需要保持與Windows XP的兼容性,並且我一直未能將轉換後的項目甚至在XP下注冊。爲了理解什麼是必要的(在搜索Stack Overflow和MSDN幾周後),我嘗試使用VS 2015從頭創建一個基於ATL的Dll,並且它不起作用。在進一步研究之前,讓我列出一些事項:Visual Studio 2015不能生成在Windows XP上成功註冊的ATL Dll

1)是的,我已經安裝了VS 2015,並啓用了對C++的支持。 2)是的,我已經設置了平臺的工具包,XP 3)是的,我已經安裝了XP的VS 2015年86再發行組件包的目標

如果我只是去通過ATL項目嚮導和添加任何COM之前停止接口,Dll在XP上成功註冊。如果我添加一個沒有任何方法的接口,regsvr32失敗,返回碼爲0xc0000005。如果我向接口添加一個方法並提供一個實現,它將繼續以相同的方式失敗。

如果您可以提供缺少的作品,我會很感激。過程中,我經歷產生一個最小的Dll大約需要5分鐘的努力,這裏是我的步驟(設置選擇最佳逼近的Dll我想端口):

所需的環境:

您需要安裝了支持XP支持的Visual Studio 2015的Win 10系統(如果在安裝時未檢查XP C++支持選項,您將收到構建錯誤;這不是默認選項),而且Windows XP系統與安裝VS 2015 x86可再發行組件(可在此處獲得:https://www.microsoft.com/en-us/download/details.aspx?id=48145

O選擇文件/新建/新建項目...

•從對話框左側的Installed/Templates/Visual C++/Windows樹中,選擇「ATL」作爲項目類型過濾器, •選擇「ATL Project」作爲項目類型,位於對話框中心的模板列表中。 •從對話框頂部的下拉列表中選擇「.NET Framework 3.5」作爲.NET Framework •將項目命名爲「DllHoopt​​y」, •選擇右下角的「創建解決方案目錄」選項對話框。 •單擊確定開始項目嚮導。

當項目嚮導出現時,當前的項目設置應該是「動態鏈接庫」。

•點擊「下一步」,而不是「完成」

在「應用程序設置」頁:

•選擇「允許的代理/存根代碼合併」, •取消選中「安全開發生命週期( SDL)檢查「。 •取消選中「支持MFC」和「支持COM + 1.0」。 •單擊「完成」創建項目&解決方案。

當項目/解決方案已創建:

•選擇「釋放」作爲配置,而「86」爲平臺。 •右鍵單擊DllHoopt​​y項目,然後選擇「屬性」。 •在屬性對話框中,確保配置和平臺分別爲「Release」和「Win32」 •如果尚未選擇,請轉到「Configuration Properties/General」面板 •更改「Platform Toolset 「到」Visual Studio 2015 - Windows XP(v140_xp)「 •單擊確定以保存更改並關閉屬性面板。

如果你在這裏停下來建立解決方案,生成的dll會成功註冊。

右鍵單擊DllHoopt​​y項目,並選擇「添加/類...」從彈出菜單中從樹彈出添加類對話框 •選擇「安裝/的Visual C++/ATL」和「ATL簡單對象「從模板列表 •單擊」添加「開始ATL簡單對象嚮導。

•在「歡迎使用ATL簡單對象嚮導」頁面上,爲對象提供Hoopt​​y的「短名稱」。這將導致所有其他字段被填寫。 •單擊「下一步」。 •單擊「下一步」,在「文件類型處理程序選項」頁

在「選項」頁上: •選擇「單一」的線程模型, •選擇「否」作爲「聚合」選項, •選擇「Custom」作爲「Interface」選項。 •取消選中「自定義」下的「自動兼容」框。 •所有「支持」框都應該取消選中。
•單擊「完成」

在這一點上和以後,所有生成的DLL將無法註冊消息「DllHoopt​​y.dll中的DllRegisterServer失敗。返回碼爲0xc0000005「

打開文件」DllHoopt​​y.idl「, •將」HRESULT Wub();「添加到」接口IHoopt​​y「(例如,更改它讀取:

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

打開「Hoopt​​y.h」 •添加:

STDMETHOD(Wub)(); 

市民:部分在CHoopt​​y類聲明

打開「Hoopt​​y結束。 cpp「 •add:

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

構建項目(使sur e Release/x86是所選配置&平臺)

•在Win XP計算機上將「DllHoopt​​y.dll」移動到本地硬盤驅動器(如果您正在VirtualBox中使用VM,則不是共享文件夾)安裝了C++可再發行組件。

在XP的機器: •彈出一個命令提示符, •導航到DllHoopt​​y.dll的位置, •運行「REGSVR32 DllHoopt​​y.dll」。

如果我的猜測是正確的,你會得到一個錯誤對話框:

「的DllRegisterServer DllHoopt​​y.dll失敗。返回碼是:0xc0000005「

我已經嘗試了許多很多事情:爲WINVER 0x0501,_WIN32_WINNT 0x0501,_ATL_XP_TARGETING以及許多其他我已經遺忘的添加了定義。沒有什麼改變結果。

+0

*我通過生成最小Dll的過程需要大約5分鐘的時間* - 找到有時間設置或具有所有這些先決條件的人的好運。 – PaulMcKenzie

回答

4
  1. 鏈接的CRT靜態 - 在配置屬性/ C/C++ /代碼生成/運行時庫選擇非DLL多線程的選項,例如在/MT發佈版本。

  2. 將Config Properties/C/C++/Command Line/Additional Options下的編譯器選項添加到/Zc:threadSafeInit-(n.b.尾隨-是開關的一部分)。

解決方法#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