2010-02-02 168 views
15

我最近瀏覽了一堆用VB6編寫的獨立實用程序應用程序,以確保Windows Vista及更高版本的註冊表虛擬化已關閉。我爲每個exe創建了一個獨立的清單文件,適當地設置了requestedExecutionLevel(其中一些需要修改HKEY_LOCAL_MACHINE註冊表項,其他則不需要),並對它們進行了測試。他們都似乎正常工作。將應用程序清單嵌入到VB6 exe中

我只剩下一個小問題。由於它們是獨立的實用程序,人們習慣於在網絡上覆制它們並手動運行它們。如果有人忘記複製清單文件以及exe文件,那麼這個exe文件將默默地寫入虛擬化的註冊表鍵值而不是真正的,導致難以調試的問題。

顯而易見的解決方案是將manifest作爲資源嵌入到exe中。所有我已經在網絡上閱讀這些文章告訴你嵌入這樣的資源:

#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 
#define RT_MANIFEST 24 
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest" 

這應該工作得很好,除了VB編譯器總是與資源ID創建應用程序圖標= 1。當我試着上面的代碼,Windows拒絕運行該exe文件,抱怨資源錯誤(我將在稍後更新這篇文章)。我嘗試將資源ID更改爲另一個編號,之後Windows成功運行程序,但未識別清單內容。

有誰知道一種方式來獲得嵌入式清單工作在VB6 EXE,或者我應該堅持使用外部文件?

UPDATE 1

以上給出的文本是.rc文件的全部內容。我把它編譯成一個.res文件是這樣的:

"%ProgramFiles%\Microsoft Visual Studio\VB98\Wizards\rc.exe" /r /fo "Resources.res" "Resources.rc"

而在VB6的項目文件中像這樣將它嵌入:

Type=Exe 
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\..\WINDOWS\system32\stdole2.tlb#OLE Automation 
Form=Main.frm 
ResFile32="Resources.res" 
IconForm="FMain" 
Startup="FMain" 
HelpFile="" 
Title="Windows Vista Registry Test - VB6" 
ExeName32="RegistryTestVB6.exe" 
Path32="" 
Command32="" 
Name="RegistryTestVB6" 
HelpContextID="0" 
CompatibleMode="0" 
MajorVer=1 
MinorVer=0 
RevisionVer=0 
AutoIncrementVer=0 
ServerSupportFiles=0 
VersionComments="Windows Vista Registry Test - VB6" 
VersionCompanyName="" 
VersionFileDescription="Windows Vista Registry Test - VB6" 
VersionLegalCopyright="" 
VersionProductName="Windows Vista Registry Test - VB6" 
CondComp="" 
CompilationType=0 
OptimizationType=0 
FavorPentiumPro(tm)=0 
CodeViewDebugInfo=0 
NoAliasing=0 
BoundsCheck=0 
OverflowCheck=0 
FlPointCheck=0 
FDIVCheck=0 
UnroundedFP=0 
StartMode=0 
Unattended=0 
Retained=0 
ThreadPerObject=0 
MaxNumberOfThreads=1 

,當我讀到編譯EXE到VS2008資源編輯器,它看起來是這樣的:

RegistryTestVB6.exe 
    Icon 
     1 [Neutral] 
    RT_MANIFEST 
     1 [English (United States)] 
    Version 
     1 [English (United States)] 

當我構建VS2008完全等效VB.NET測試應用程序,然後加載到資源edito R,它看起來像這個:

RegistryTestNET.exe 
    Icon 
     32512 [Neutral] 
    RT_MANIFEST 
     1 [Neutral] 
    Version 
     1 [Neutral] 

更新2

測試 - 對.NET的exe運行在Windows XP和Windows 7。但是細,VB6的EXE產生在XP下面的錯誤:

此應用程序無法啓動,因爲應用程序配置不正確。重新安裝該應用程序可能會解決此問題。

和7以下錯誤:

的應用已啓動失敗,因爲其側由端配置不正確。請參閱應用程序事件日誌或使用命令行sxstrace.exe工具獲取更多詳細信息。

尋找在事件日誌中我看到下面的條目:

激活上下文生成失敗的「RegistryTestVB6.exe」。第10行的清單文件或策略文件「RegistryTestVB6.exe」中出現錯誤。無效的Xml語法。

不用說,XML是無效的,它是完全相同的文件與我使用.NET EXE相同的編碼,並且這一個工程。

解決方案

VB6的編譯器確實需要包含在資源的任意文本文件必須是4個字節的整數倍。我只是增加空間的XML直到記事本+ +告訴我,文件總大小,包括BOM是4.

感謝兩個邁克爾和吉姆·多指着我在正確的方向。只是可惜我不能將你們都標記爲答案!

+0

不知道你的問題是什麼,但它不是圖標。每類資源(RT_MANIFEST,RT_ICON)都有它自己的id名稱空間。你能給我們更多的.rc文件的文本嗎? – 2010-02-02 09:14:25

+0

我依稀記得有關XP和Vista希望在不同的資源ID的清單的東西。嘗試使用RESOURCE_ID 2,或者可能在ID 1和ID 2中放入相同的清單。 – 2010-02-02 09:25:45

+0

@JohnKnoeller資源ID實際上有一個含義並可以產生不同的結果,請參見[here](http://blogs.msdn.com/b /junfeng/archive/2007/06/26/rt-manifest-resource-and-isolation-aware-enabled.aspx)以獲取詳細信息。 – takrl 2013-01-21 10:34:56

回答

8

有趣的是,我必須做同樣的事情最近。按照克里斯蒂安所描述的步驟,我第一次通過了。對於propsperity,這裏是整個工作流程我跟着:

  1. 創建一個RC文件作爲原單問題
  2. 創建一個app.manifest具有以下內容描述:用於

ManifestImage http://img638.imageshack.us/img638/3364/manifesta.png 圖片保留空白字符,這對於此工作非常重要。如在先前的答案指出,文件大小必須是4

  • 然RC.EXE如在原來的問題對抗RC來產生res文件
  • 描述
  • 編輯我Project.VBP文件以包括靠近頂部以下行:
  • ResFile32 = 「Resources.res」

  • 內置標準EXE vb6 e nvironment。當Vista或win7的機器上部署,屏蔽顯示出來,並會提示用戶以管理員身份運行。當打開工作室的EXE文件,我看到了以下資源:
  • alt text http://img688.imageshack.us/img688/4879/finalresources.png

    如果您還是有問題,讓我知道,我會盡我所能與大家分享。除此之外,我不知道要告訴你什麼,除了Works on my Machine!

    +0

    謝謝邁克。我還沒有機會測試這個,所以我問你:你的清單在文件的開頭是否包含UTF-8字節順序標記? – 2010-02-11 08:36:34

    +0

    基督徒 - 不,它不。事實上,Notepad ++告訴我,我的app.manifest文件的編碼是ANSI。 – 2010-02-11 20:23:40

    8

    VB6具有任何資源元素中的異常行爲必須是4的長度的整數倍。嘗試用空格填充.RC文件,並查看是否改變了行爲。

    此外,您可以使用VB6的IDE,而不是編輯VBP添加資源。效果可能相同,但資源編輯器是執行此操作的標準方法。

    +0

    對不起,我的意思是說,將MANIFEST填充到4的倍數。 – 2010-02-02 13:22:35

    +0

    謝謝吉姆,不知道。根據純粹的巧合,根據VS2008十六進制查看器,我的清單資源條目已經是16個字節的確切倍數。我懷疑這可能是一個編碼問題。我正在嘗試不同的組合以查看哪些方法有效,稍後我會更新我的帖子。 – 2010-02-02 13:53:28

    +0

    @JimMack我知道這從我自己的經驗來看是真實的,但是你有沒有在任何地方看到過它的權威記錄(例如,微軟)? – 2012-10-19 17:16:20

    6

    使用Resource Compiler (rc.exe)是漫長的。在可執行文件中嵌入應用程序清單是一種非常簡單的選項,無論是C++還是VB6還是其他任何語言。 The Manifest Tool (mt.exe)是專門爲嵌入在二進制文件中的清單編寫的,並且免費提供給Windows SDK。使用mt.exe的附加好處是它會自動處理任何必要的填充。

    在編譯二進制文件後,只需運行以下命令行即可。我已經使用了Visual C++ 2005編譯器內部使用的命名約定,其中清單文件名包含完整的程序名稱並附有「.intermediate.manifest」。

    mt.exe -nologo -manifest "program.exe.intermediate.manifest" -outputresource:"program.exe;#1

    更新:我本人曾在自動生成過程,現在使用這種與VB6的可執行文件超過兩年。它非常成功,我們已經從我們的迴歸測試中消除了特定於體現的操作系統兼容性測試。

    +0

    謝謝約翰,瞭解這樣的工具總是有用的。 – 2011-07-13 07:13:15