将应用程序清单嵌入到VB6 exe中 [英] Embedding an application manifest into a VB6 exe

查看:116
本文介绍了将应用程序清单嵌入到VB6 exe中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近浏览了许多用VB6编写的独立实用程序应用程序,以确保Windows Vista及更高版本的注册表虚拟化功能已关闭.我为每个exe创建了一个独立的清单文件,适当地设置了requestedExecutionLevel(其中一些需要修改HKEY_LOCAL_MACHINE注册表项,而其他则不需要),并对其进行了测试.它们似乎都可以正常工作.

I have recently gone through a bunch of standalone utility apps written in VB6 to make sure that registry virtualization is turned off for Windows Vista and above. I created a standalone manifest file for each exe, set the requestedExecutionLevel appropriately (some of them need to modify HKEY_LOCAL_MACHINE registry keys, others do not), and tested them. They all appear to work correctly.

我只剩下一个小问题了.由于它们是独立的实用程序,因此人们习惯于在网络上复制它们并手动运行它们.如果有人忘记复制清单文件和exe文件,那么exe文件将以静默方式而不是真实的注册表项写入虚拟化的注册表项,从而导致难以调试的问题.

I have only one small problem remaining. Since they are standalone utilities, people are used to just copying them around the network and running them manually. If anyone forgets to copy the manifest file as well as the exe, then the exe will silently write to the virtualized registry key instead of the real one and cause hard-to-debug problems.

显而易见的解决方案是将清单作为资源嵌入到exe中.我在网上阅读的所有文章都告诉您嵌入这样的资源:

The obvious solution is to embed the manifest into the exe as a resource. All the articles I have read on the net tell you to embed the resource like this:

#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成功运行了该程序,但无法识别清单内容.

This should work just fine, except that the VB compiler always creates the application icon with resource ID = 1. When I tried the above code, Windows refused to run the exe, complaining about a resource error (I'll update this post with the details later). I tried changing the resource ID to another number, after which Windows ran the program successfully but did not recognise the manifest contents.

有人知道让嵌入式清单在VB6 exe中工作的方法吗,还是我应该坚持使用外部文件?

Does anyone know of a way to get an embedded manifest to work in a VB6 exe, or should I just stick with an external file?

更新1

上面给出的文本是.rc文件的全部内容.我将其编译为.res文件,如下所示:

The text given above is the whole content of the .rc file. I compile it to a .res file like this:

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

并将其嵌入到VB6项目文件中,如下所示:

And embed it in the VB6 project file like this:

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

当我在VS2008资源编辑器中读取编译后的exe时,它看起来像这样:

When I read the compiled exe into the VS2008 resource editor, it looks like this:

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

当我在VS2008中构建一个完全等效的VB.NET测试应用程序,然后将其加载到资源编辑器中时,它看起来像这样:

When I construct an exact equivalent VB.NET test app in VS2008, then load that into the resource editor, it looks like this instead:

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

更新2

测试-.NET exe在Windows XP和Windows 7上均可正常运行.但是,VB6 exe在XP上会产生以下错误:

Testing - the .NET exe runs fine on both Windows XP and Windows 7. However, the VB6 exe produces the following error on XP:

此应用程序无法启动,因为应用程序配置不正确.重新安装该应用程序可能会解决此问题.

以及7上的以下错误:

该应用程序无法启动,因为其并行配置不正确.请参阅应用程序事件日志或使用命令行sxstrace.exe工具了解更多详细信息.

在事件日志中,我看到以下条目:

Looking in the event log I see the following entry:

"RegistryTestVB6.exe"的激活上下文生成失败.第10行上的清单文件或策略文件"RegistryTestVB6.exe"出错.无效的Xml语法.

不用说XML并不是无效的,它是与用于.NET exe的文件完全相同的文件,并且具有相同的编码.

Needless to say the XML isn't invalid, it's exactly the same file with the same encoding that I used for the .NET exe, and that one works.

解决方案

VB6编译器确实确实要求资源中包含的任意文本文件必须是4字节的精确倍数.我只是在XML中添加了空格,直到Notepad ++告诉我,包括BOM在内的文件总大小是4的倍数.

The VB6 compiler does indeed require that an arbitrary text file included in a resource must be an exact multiple of 4 bytes. I simply added spaces to the XML until Notepad++ told me that the total file size including BOM was a multiple of 4.

感谢迈克尔和吉姆为我指明了正确的方向.遗憾的是,我不能将你们两个都标记为答案!

Thanks to both Michael and Jim for pointing me in the correct direction. Just a pity I can't mark you both as the answer!

推荐答案

有趣的是,我最近不得不做完全相同的事情.按照克里斯蒂安(Christian)所描述的步骤,我第一次尝试了它.为了繁荣,这是我遵循的整个工作流程:

Interestingly enough, I had to do the exact same thing recently. Following the steps Christian described, I got it to work the first time through. For prosperity, here is the entire workflow I followed:

  1. 按照原始问题中的说明创建RC文件
  2. 创建了一个app.manifest,保留了空白字符,这些字符对于此功能非常重要.如先前的回答所述,文件大小必须为4的倍数.

  1. Created a RC file as described in the orginal question
  2. Created a app.manifest, preserving whitespace characters, which are VERY IMPORTANT for this to work. As stated in previous answers, the file size must be a multiple of 4.

按照针对rc的原始问题中所述运行RC.EXE以生成.res文件

Ran RC.EXE as described in the original question against the rc to generate the .res file

ResFile32 ="Resources.res"

ResFile32="Resources.res"

  1. 在标准vb6环境中构建EXE.当部署在vista或win7机器上时,将显示防护罩,并提示用户以管理员身份运行.在Studio中打开EXE文件时,我验证了资源.

  1. Built EXE in standard vb6 environment. When deployed on a vista or win7 machine, the shield shows up and the user is prompted to run as administrator. When opening the EXE file in studio, I verified the resources.

Notepad ++告诉我,我的app.manifest文件上的编码为ANSI.该文件的开头没有字节顺序标记.

Notepad++ tells me that the encoding on my app.manifest file is ANSI. It did not include an byte order mark at the start of the file.

如果您仍然遇到麻烦,请告诉我,我会尽力与您分享.除此之外,除了在我的机器上工作之外,我不确定要告诉你什么!

If you are still having troubles, let me know and I'll share whatever I can with you. Other than that, I'm not sure what to tell you other than Works on my Machine!

这篇关于将应用程序清单嵌入到VB6 exe中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆