C++ 读取应用程序的清单文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/420852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:15:13  来源:igfitidea点击:

reading an application's manifest file?

c++windowsvisual-c++manifest

提问by Brian R. Bondy

Is there an easy way to read an application's already embedded manifest file?

有没有一种简单的方法来读取应用程序已经嵌入的清单文件?

I was thinking along the lines of an alternate data stream?

我在考虑替代数据流的思路?

回答by Roger Lipscombe

Windows manifest files are Win32 resources. In other words, they're embedded towards the end of the EXE or DLL. You can use LoadLibraryEx, FindResource, LoadResource and LockResource to load the embedded resource.

Windows 清单文件是 Win32 资源。换句话说,它们嵌入在 EXE 或 DLL 的末尾。您可以使用 LoadLibraryEx、FindResource、LoadResource 和 LockResource 来加载嵌入的资源。

Here's a simple example that extracts its own manifest...

这是一个简单的例子,它提取自己的清单......

BOOL CALLBACK EnumResourceNameCallback(HMODULE hModule, LPCTSTR lpType,
    LPWSTR lpName, LONG_PTR lParam)
{
    HRSRC hResInfo = FindResource(hModule, lpName, lpType);
    DWORD cbResource = SizeofResource(hModule, hResInfo);

    HGLOBAL hResData = LoadResource(hModule, hResInfo);
    const BYTE *pResource = (const BYTE *)LockResource(hResData);

    TCHAR filename[MAX_PATH];
    if (IS_INTRESOURCE(lpName))
        _stprintf_s(filename, _T("#%d.manifest"), lpName);
    else
        _stprintf_s(filename, _T("%s.manifest"), lpName);

    FILE *f = _tfopen(filename, _T("wb"));
    fwrite(pResource, cbResource, 1, f);
    fclose(f);

    UnlockResource(hResData);
    FreeResource(hResData);

    return TRUE;   // Keep going
}

int _tmain(int argc, _TCHAR* argv[])
{
    const TCHAR *pszFileName = argv[0];

    HMODULE hModule = LoadLibraryEx(pszFileName, NULL, LOAD_LIBRARY_AS_DATAFILE);
    EnumResourceNames(hModule, RT_MANIFEST, EnumResourceNameCallback, NULL);
    FreeLibrary(hModule);
    return 0;
}

Alternatively, you can use MT.EXE from the Windows SDK:

或者,您可以使用 Windows SDK 中的 MT.EXE:

>mt -inputresource:dll_with_manifest.dll;#1 -out:extracted.manifest

回答by bk1e

You can extract/replace/merge/validate manifests using the command line manifest tool, mt.exe, which is part of the Windows SDK:

您可以使用命令行清单工具提取/替换/合并/验证清单mt.exe,该工具是 Windows SDK 的一部分:

C:\Program Files\Microsoft SDKs\Windows\v6.1>mt /?
Microsoft (R) Manifest Tool version 5.2.3790.2075
...
> To extract manifest out of a dll:
mt.exe -inputresource:dll_with_manifest.dll;#1 -out:extracted.manifest

EDIT: I found the tool in C:\Program Files\Microsoft SDKs\Windows\v6.1\bin

编辑:我在 C:\Program Files\Microsoft SDKs\Windows\v6.1\bin 中找到了该工具

回答by guest

Open the file in Notepad. The thing's in plain text.

在记事本中打开文件。事情是纯文本的。

Screen grab

屏幕抓取

回答by jeffm

There's a manifest viewer tool available here-- I don't know if the author will make source code available.

有可用的清单查看器工具在这里-我不知道,如果作者将提供源代码。

回答by Mike

Resource Tuner would be nice if it supported x64 code, but as of today it's still only for 32-bit apps. Resource Hacker (the newest public beta) does support both x86 and x64 which is available from here: http://angusj.com/resourcehacker/

Resource Tuner 如果支持 x64 代码会很好,但截至今天,它仍然仅适用于 32 位应用程序。Resource Hacker(最新的公开测试版)确实支持 x86 和 x64,可以从这里获得:http: //angusj.com/resourcehacker/

回答by Wylder

The easiest way to view/edit manifests in compiled apps is using Resource Tuner: http://www.restuner.com/tour-manifest.htm

在已编译的应用程序中查看/编辑清单的最简单方法是使用 Resource Tuner:http: //www.restuner.com/tour-manifest.htm

In some cases, it's more robust than mt.exe from MS, and it's a visual tool.

在某些情况下,它比 MS 的 mt.exe 更强大,并且它是一个可视化工具。

回答by Samphan

Working a bit from Roger's code, here's the code that I use. It assume that the Manifest is at id #1. I guess this is the default for .exe. See the comment by Wedge, you may have to also check id #2 if you're working with DLL.

从 Roger 的代码开始,这是我使用的代码。它假设 Manifest 位于 id #1。我猜这是 .exe 的默认设置。请参阅 Wedge 的评论,如果您正在使用 DLL,您可能还需要检查 id #2。

    HMODULE module = ::LoadLibraryEx(pathname, NULL, LOAD_LIBRARY_AS_DATAFILE);
    if (module == NULL)
        return false;
    HRSRC resInfo = ::FindResource(module, MAKEINTRESOURCE(1), RT_MANIFEST); // resource id #1 should be the manifest
    if (resInfo) {
        HGLOBAL resData = ::LoadResource(module, resInfo);
        DWORD resSize = ::SizeofResource(module, resInfo);
        if (resData && resSize) {
            const char *res = (const char *)::LockResource(resData); // the manifest
            if (res) {
                // got the manifest
            }
            ::UnlockResource(resData);
        }
        ::FreeResource(resData);
    }
    ::FreeLibrary(module);

回答by Rahul Tripathi

Fix this problem by deleting the developers license (*_TemporaryKey.pfx) from the project or change Name of .pfx .

通过*_TemporaryKey.pfx从项目中删除开发人员许可证 ( ) 或更改 .pfx 的名称来解决此问题。

回答by chksr

As a side reminder: remember that manifests can also be standalone files with the same name as the app (extended by ".manifest").

附带提醒:请记住,清单也可以是与应用程序同名的独立文件(以“.manifest”为扩展名)。

So if you want to check out which manifest is really used at runtime, this must be taken into account.

因此,如果您想查看运行时真正使用了哪个清单,则必须考虑到这一点。