将应用程序清单嵌入VB6 exe
我最近浏览了大量用VB6编写的独立实用程序应用程序,以确保Windows Vista及以上版本的注册表虚拟化已关闭。我为每个exe创建了一个独立的清单文件,适当地设置了将应用程序清单嵌入VB6 exe,vb6,resources,uac,manifest,Vb6,Resources,Uac,Manifest,我最近浏览了大量用VB6编写的独立实用程序应用程序,以确保Windows Vista及以上版本的注册表虚拟化已关闭。我为每个exe创建了一个独立的清单文件,适当地设置了requestedExecutionLevel(其中一些需要修改HKEY\U LOCAL\U MACHINE注册表项,其他则不需要),并对它们进行了测试。它们似乎都工作正常 我只剩下一个小问题。由于它们是独立的实用程序,人们习惯于在网络上复制它们并手动运行它们。如果有人忘记复制清单文件和exe,则exe将以静默方式写入虚拟化注册表
requestedExecutionLevel
(其中一些需要修改HKEY\U LOCAL\U MACHINE
注册表项,其他则不需要),并对它们进行了测试。它们似乎都工作正常
我只剩下一个小问题。由于它们是独立的实用程序,人们习惯于在网络上复制它们并手动运行它们。如果有人忘记复制清单文件和exe,则exe将以静默方式写入虚拟化注册表项,而不是真正的注册表项,并导致难以调试的问题
显而易见的解决方案是将清单作为资源嵌入到exe中。我在网上读到的所有文章都告诉你要像这样嵌入资源:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
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
RegistryTestVB6.exe
Icon
1 [Neutral]
RT_MANIFEST
1 [English (United States)]
Version
1 [English (United States)]
这应该可以正常工作,除了VB编译器总是创建资源ID为1的应用程序图标。当我尝试上面的代码时,Windows拒绝运行exe,抱怨资源错误(稍后我将用详细信息更新本文)。我尝试将资源ID更改为另一个数字,之后Windows成功运行了该程序,但无法识别清单内容
有人知道如何让嵌入式清单在VB6 exe中工作,还是我应该只使用外部文件
更新1
上面给出的文本是.rc
文件的全部内容。我将其编译为.res
文件,如下所示:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
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
RegistryTestVB6.exe
Icon
1 [Neutral]
RT_MANIFEST
1 [English (United States)]
Version
1 [English (United States)]
%ProgramFiles%\Microsoft Visual Studio\VB98\Wizards\rc.exe”/r/fo“Resources.res”“Resources.rc”
并将其嵌入VB6项目文件中,如下所示:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
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
RegistryTestVB6.exe
Icon
1 [Neutral]
RT_MANIFEST
1 [English (United States)]
Version
1 [English (United States)]
当我将编译后的exe读入VS2008资源编辑器时,它如下所示:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
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
RegistryTestVB6.exe
Icon
1 [Neutral]
RT_MANIFEST
1 [English (United States)]
Version
1 [English (United States)]
当我在VS2008中构造一个完全等效的VB.NET测试应用程序,然后将其加载到资源编辑器中时,它看起来是这样的:
RegistryTestNET.exe
Icon
32512 [Neutral]
RT_MANIFEST
1 [Neutral]
Version
1 [Neutral]
更新2
测试-在Windows XP和Windows 7上.NET exe都可以正常运行。但是,VB6 exe在XP上会产生以下错误:
由于应用程序配置不正确,此应用程序无法启动。重新安装应用程序可能会解决此问题
以及7上的以下错误:
应用程序无法启动,因为其并行配置不正确。有关详细信息,请参阅应用程序事件日志或使用命令行sxstrace.exe工具
查看事件日志,我看到以下条目:
“RegistryTestVB6.exe”的激活上下文生成失败。清单或策略文件“RegistryTestVB6.exe”第10行出现错误。无效的Xml语法
不用说XML不是无效的,它与我在.NET exe中使用的编码完全相同,并且有效
分辨率
VB6编译器确实要求资源中包含的任意文本文件必须是4字节的精确倍数。我只是在XML中添加了空格,直到Notepad++告诉我,包括BOM表在内的总文件大小是4的倍数
感谢迈克尔和吉姆为我指明了正确的方向。很遗憾,我不能把你们两个都当作答案 VB6有一个怪癖,即任何资源元素的长度必须是4的精确倍数。尝试用空格填充清单文件以确保这一点,并查看这是否会改变行为 这一怪癖在一本书中有记载
此外,还可以使用VB6 IDE添加资源,而不是编辑VBP。效果可能是一样的,但资源编辑器是实现这一点的标准方法。有趣的是,我最近也做了同样的事情。按照Christian描述的步骤,我第一次就完成了。为了繁荣,以下是我遵循的整个工作流程:
mt.exe-nologo-manifest“program.exe.intermediate.manifest”-输出资源:“program.exe;#1
更新:我个人已经在VB6可执行文件的自动生成过程中使用了两年多。它非常成功,我们已经消除了