取文件属性

取文件属性:GetFileVersionInfoSize,GetFileVersionInfo,VerQueryValue三个函数的配合
 

右键点击一个文件,看它的属性,会发现有很多东西。查了一下,有一个结构体可以用来获得文件的属性,不过得到的东西很有限,隐约记得是7个,比如文件名称,创建时间什么的。而查看不同的文件属性页里的内容是不一样的,比如以下一个exe文件



这里面的产品说明之类的东西在有些文件里是没有的。当然,我还没研究太深,用一个可能不恰当的名词吧。只是觉得这些应该不属于“基本属性”,而本文开篇所提到的那些属性属于基本属性。像文件名称,各种时间之类的,应该所有文件都会有。

    再看这些属性们,会觉得很眼熟,打开一个VC++工程,可以在workspace里面看到这个

    打开这个文件,就能看到具体条目。

    对了,就是它,属性页里那些乱七八糟的“键值对”们就是在这里来的。下面就要得到它们。使用GetFileVersionInfoSize,GetFileVersionInfo,VerQueryValue三个函数配合使用。前两个好说,不过第三个VerQueryValue弄了好久也弄不明白。网上搜到了一个ID为EnochShen的网友(CSDN)的回帖,如下。先做一下搬运工。感谢EnochShen。在他的代码上面加一些我自己的说明文字吧。不作说明的注释都是我加上去的。不过,除了我注出来的一个地方用TCHAR不行之外,其他地方我全是用的TCHAR。

char* szFileName = "C:\\EnochShen.exe "; //文件的全路径,更实用的是动态获取
DWORD dwSize = GetFileVersionInfoSize(szFileName,NULL); //可查MSDN,函数用法。MSDN上说最后一个参数是需要置0的,我就弄了一个置0的变量DWORD dwVerSetZero = 0;把地址加进来,可看这个用法直接塞个NULL,试了下,也行。搞不明白有什么区别。
LPVOID pBlock = malloc(dwSize); //我没这样做,而是TCHAR* szVersionInfo = new TCHAR[4096];也没有问题,当然pBlock就改成了szVersionInfo这个名字
GetFileVersionInfo(szFileName,0,dwSize,pBlock);

char* pVerValue = NULL; //这里不能用TCHAR*,在后面代码VerQueryValue(szVersionInfo, strSubBlock, (LPVOID*)&pVerValue, &nBytes);中会出问题,应该是编译后搞成UNICODE的双字节了。

UINT nSize = 0;
VerQueryValue(pBlock,TEXT( "\\VarFileInfo\\Translation "),
(LPVOID*)&pVerValue,&nSize); //这是得到语言什么的,死板地套用就行了,我也还不明白

CString strSubBlock,strTranslation,strTemp;
strTemp.Format( "000%x ",*((unsigned short int *)pVerValue));
strTranslation = strTemp.Right(4);
strTemp.Format( "000%x ",*((unsigned short int *)&pVerValue[2]));
strTranslation += strTemp.Right(4);
//【原】080404b0为中文,040904E4为英文 //此注释不理解,其实我调试时,不是这两个数值,也还堪用。难道是火星文?

//【原】文件描述
strSubBlock.Format( "\\StringFileInfo\\%s\\FileDescription ",strTranslation);

//上面这个字符串很重要,要读什么东西出来就是靠它了。后来想想,我只所以不会用,就是这个串不会用,总也不知道要取的属性在这里叫什么名字。当然,我用的形式如下

//strSubBlock.Format( _T("\\StringFileInfo\\%s\\ProductName"),strTranslation);TCHAR

//不过我只用到了ProductName这一项,其他的都按原样列在下面。备忘吧。
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue,&nSize);
strSubBlock.ReleaseBuffer();
strTemp.Format( "文件描述: %s ",pVerValue);
AfxMessageBox(strTemp); //这个函数得改。我与EnochShen的上下文环境俨然不一样。我这里用不了。

//【原】内部名称
strSubBlock.Format( "\\StringFileInfo\\%s\\InternalName ",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue,&nSize);
strSubBlock.ReleaseBuffer();
strTemp.Format( "文件描述: %s ",pVerValue);
AfxMessageBox(strTemp);

//【原】合法版权
strSubBlock.Format( "\\StringFileInfo\\%s\\LegalTradeMarks ",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue,&nSize);
strSubBlock.ReleaseBuffer();
strTemp.Format( "合法版权: %s ",pVerValue);
AfxMessageBox(strTemp);

//【原】原始文件名
strSubBlock.Format( "\\StringFileInfo\\%s\\OriginalFileName ",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue,&nSize);
strSubBlock.ReleaseBuffer();
strTemp.Format( "原始文件名: %s ",pVerValue);
AfxMessageBox(strTemp);

//【原】产品名称
strSubBlock.Format( "\\StringFileInfo\\%s\\ProductName ",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue,&nSize);
strSubBlock.ReleaseBuffer();
strTemp.Format( "产品名称: %s ",pVerValue);
AfxMessageBox(strTemp);

//【原】产品版本
strSubBlock.Format( "\\StringFileInfo\\%s\\ProductVersion ",strTranslation);
VerQueryValue(pBlock,strSubBlock.GetBufferSetLength(256),(LPVOID*)&pVerValue,&nSize);
strSubBlock.ReleaseBuffer();
strTemp.Format( "产品版本: %s ",pVerValue);
AfxMessageBox(strTemp);

free(pBlock); //我的是new出来的TCHAR,也free了一下。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值