列举可执行文件的所有版本描述字符串
来源:互联网 发布:麦当劳工资算法 编辑:程序博客网 时间:2024/06/06 04:23
程序开头加上如下引用,不然编译不过。
#pragma comment(lib, "Version.lib")
结构定义:
struct LANGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
};
struct VS_VERSIONINFO
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[1];
WORD wPadding1[1]; //以零填充szKey以对齐数据为32位(4个字节)
VS_FIXEDFILEINFO Value;
WORD wPadding2[1];
WORD wChildren[1];
};
struct KEYSTRING
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[1];
WORD Padding[1];
WORD Value[1];
};
struct STRINGTABLE
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[1];
WORD Padding[1];
KEYSTRING Children[1];
};
struct STRINGFILEINFO
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[1];
WORD Padding[1];
STRINGTABLE Children[1];
};
VS_VERSIONINFO及相关的结构是个相当复杂的结构,主要是因为他它里面的szKey及 诸如Children等成员的大小并不确定,所以在定义这些结构时都是以1为单位,在实际应用时才确定其具体地址。
定义两个字符串于存储字段名及字段值:
CHAR szKey[MAX_PATH]={0}, szValue[MAX_PATH]={0};
因为各字符串都是以宽字符形式存储的,所以要进行转换,相关函数:
//*****************************************************************************
// 宽字符串转为标准字符串
// swSource:宽字符串 szDescription=保存标准字符串的缓冲区 nSize = 缓冲区大小
//*****************************************************************************
BOOL TransformStringWideToAnsi(LPCWSTR swSource, LPSTR szDescription, UINT nSize)
{
UINT nLength = WideCharToMultiByte(CP_ACP, NULL, swSource, -1, NULL, 0, NULL, NULL);
if((nLength<=0)||(nSize<nLength)) return FALSE;
WideCharToMultiByte(CP_ACP, NULL, swSource, -1, szDescription, nLength, NULL, NULL);
szDescription[nLength-1]=0;
return TRUE;
}
//*****************************************************************************
// 列举文件描述信息
// lpszAppFile=文件名
//*****************************************************************************
BOOL ListAppDescription(LPCSTR lpszAppFile)
{
BOOL fgRet = FALSE;
DWORD dwHandle, dwSize;
LPSTR lpFileName = (LPSTR)lpszAppFile;
//获取版本信息区大小
dwSize = ::GetFileVersionInfoSize(lpFileName, &dwHandle);
if(dwSize == 0) return FALSE;
//建立缓冲区,
LPBYTE lpBuffer = new BYTE[dwSize];
ZeroMemory(lpBuffer, dwSize);
do
{
//读取版本信息
if(!::GetFileVersionInfo(lpFileName, 0, dwSize, lpBuffer)) break;
//获取语言代码
UINT nSize;
LANGANDCODEPAGE *lpTranslate = NULL;
if(!::VerQueryValue(lpBuffer, _T("\\VarFileInfo\\Translation"), (LPVOID *)(&lpTranslate), &nSize)) break;
//定位VS_VERSIONINFO结构体
VS_VERSIONINFO *pVerInfo;
pVerInfo = (VS_VERSIONINFO *)lpBuffer;
if(pVerInfo->wValueLength == 0) break;
if(!wcscmp(pVerInfo->szKey, (WCHAR *)"VS_VERSION_INFO")) break;
//定位VS_FIXEDFILEINFO结构体
VS_FIXEDFILEINFO *pFixedInfo;
nSize = wcslen(pVerInfo->szKey);
LPBYTE pOffsetBytes = (BYTE *)pVerInfo->szKey + ((nSize+1)*sizeof(WCHAR)); //跳过szkey
pFixedInfo = (VS_FIXEDFILEINFO *)(pOffsetBytes+(nSize*sizeof(WCHAR))%4); //修正偏移地址
if(pFixedInfo->dwSignature != 0xfeef04bd) break; //检查标记
//定位STRINGFILEINFO结构体
STRINGFILEINFO *pStringFileInfo;
pOffsetBytes = (BYTE *)pFixedInfo + sizeof(VS_FIXEDFILEINFO); //跳过VS_FIXEDFILEINFO即为STRINGFILEINFO
pStringFileInfo = (STRINGFILEINFO *)pOffsetBytes;
//定位STRINGTABLE结构体
STRINGTABLE *pStringTable;
nSize = wcslen(pStringFileInfo->szKey);
pOffsetBytes = (BYTE *)pStringFileInfo->szKey + ((nSize+1)*sizeof(WCHAR));
pStringTable = (STRINGTABLE *)(pOffsetBytes+(nSize*sizeof(WCHAR))%4);
//定位KEYSTRING结构体
KEYSTRING *pKeyString;
nSize = wcslen(pStringTable->szKey);
pOffsetBytes = (BYTE *)pStringTable->szKey + ((nSize+1)*sizeof(WCHAR)); //跳过块头(中文(080404b0))
pOffsetBytes += (nSize*sizeof(WCHAR))%4;
WCHAR *pwString=NULL, swKeyName[MAX_PATH];
TransformStringAnsiToWide(lpszKeyName, swKeyName, MAX_PATH);
while((pOffsetBytes-(BYTE *)pStringTable)<pStringTable->wLength)
{
pKeyString = (KEYSTRING *)pOffsetBytes; //KEYSTRING结构体
nSize = wcslen(pKeyString->szKey); //跳过KEY_NAME
pwString = pKeyString->szKey+nSize+1; //算上结束字符
pwString += (nSize%4)/sizeof(WCHAR); //对齐32位,得到KEY_VALUE地址
//转换为标准字符串
TransformStringWideToAnsi(pKeyString->szKey, szKey, MAX_PATH);
if(pKeyString->wValueLength) TransformStringWideToAnsi(pwString, szValue, MAX_PATH);
//显示部分略
//strcat(szKey, "=");
//strcat(szKey, szValue);
//ShowMessage(szKey);
//计算下一项地址
pOffsetBytes += pKeyString->wLength;
pOffsetBytes += pKeyString->wLength%4; //对齐32位
}
}while(FALSE);
delete []lpBuffer;
return fgRet;
}
- 列举可执行文件的所有版本描述字符串
- WINDOWS下获得可执行文件的版本描述字符串
- 列举 所有的 culture
- 列举当前所有的进程
- 列举当前运行的所有进程
- 列举正在运行的所有应用程序
- 列举linux进程打开的所有文件
- Iphone中列举所有的字体
- 列举出所有进程(包括隐藏的)
- 列举本地所有网络的活动进程
- 列举iOS系统下的所有字体。
- 查找所有可执行文件的脚本
- android版本更迭对应的API列举
- 列举常用的结构标记,并描述其作用。
- 通过读取xml文件存储的可执行文件描述符,获取可执行文件名称,并启动可执行文件
- 列举所有进程
- 删除一个目录下面的所有可执行文件
- 如何列举出网络上所有的SQL Server服务器
- maven 自动发布更新本地和远程仓库
- Spark核心开发者:性能超Hadoop百倍,算法实现仅有其1/10或1/100
- hdu 1686 KMP
- 分数类-运算符重载修改bug
- MIT技术评论评选2013十大突破性技术:深度学习居首
- 列举可执行文件的所有版本描述字符串
- Weka开发[4]-特征选择
- 时间格式
- mtk android sd卡调试
- 全排列(2)----邻位对换法
- Struts2动态方法调用
- Controllers控制器部份
- URL中“#”号的作用
- 简单ajxa提交