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

时间:2009-01-07 15:57:02

标签: c++ windows visual-c++ manifest

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

我正在考虑备用数据流?

9 个答案:

答案 0 :(得分:38)

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

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

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;
}

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

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

答案 1 :(得分:26)

您可以使用命令行清单工具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

编辑:我在C:\ Program Files \ Microsoft SDKs \ Windows \ v6.1 \ bin

中找到了该工具

答案 2 :(得分:18)

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

Screen grab

答案 3 :(得分:10)

有一个可用的清单查看器工具here - 我不知道作者是否会提供源代码。

答案 4 :(得分:4)

如果它支持x64代码,资源调优器会很好,但截至今天它仍然只适用于32位应用程序。资源黑客(最新的公共测试版)确实支持x86和x64,可以从这里获得: http://angusj.com/resourcehacker/

答案 5 :(得分:2)

在编译应用中查看/编辑清单的最简单方法是使用资源调优器: http://www.restuner.com/tour-manifest.htm

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

答案 6 :(得分:1)

从罗杰的代码中稍微运用一下,这是我使用的代码。它假设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);

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

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