有没有一种简单的方法读取一个应用程序已经嵌入的清单文件?
我在考虑使用备用数据流的方式?
有没有一种简单的方法读取一个应用程序已经嵌入的清单文件?
我在考虑使用备用数据流的方式?
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
您可以使用命令行清单工具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
不同的位置:
inputresource
参数中使用的语法进行一些转义,方法如下:mt.exe "-inputresource:dll_with_manifest.dll;#1" -out:extracted.manifest
- mzabaluev在记事本中打开该文件。这个东西是纯文本。
如果 Resource Tuner 支持 x64 代码就更好了,但是截至今天,它仍然只支持 32 位应用程序。Resource Hacker(最新的公共测试版)支持 x86 和 x64,可以从这里下载:http://angusj.com/resourcehacker/
最简单的查看/编辑已编译应用程序中清单的方法是使用资源调整工具:
http://www.restuner.com/tour-manifest.htm在某些情况下,它比来自微软的mt.exe更强大,并且是一种可视化工具。
在 Roger 的代码基础上稍作修改,这是我使用的代码。它假设清单文件位于 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);
Sysinternals的"sigcheck -m"会转储一个exe的清单。(你可以从live.sysinternals.com上使用wget进行下载)。
通过从项目中删除开发人员许可证 (*_TemporaryKey.pfx
) 或更改 .pfx 的名称来解决此问题。
UnlockResource
和FreeResource
都已经过时。 - ghord