文件 详细信息
本帖最后由 gz13802424 于 2019-1-15 20:13 编辑今天太闲了,翻出些旧代码进行优化,在优化字体安装这一部分时,发现Au3自带的FileGetVersion只能查询到文件的部分信息 $FV_COMMENTS ("Comments") - 注释
$FV_COMPANYNAME ("CompanyName") - 公司名称
$FV_FILEDESCRIPTION ("FileDescription") - 文件说明
$FV_FILEVERSION ("FileVersion") - 文件版本
$FV_INTERNALNAME ("InternalName") - 内部名称
$FV_LEGALCOPYRIGHT ("LegalCopyright") - 法律版权
$FV_LEGALTRADEMARKS ("LegalTrademarks") - 法律商标
$FV_ORIGINALFILENAME ("OriginalFilename") - 原始文件名
$FV_PRODUCTNAME ("ProductName") - 产品名称
$FV_PRODUCTVERSION ("ProductVersion") - 产品版本
$FV_PRIVATEBUILD ("PrivateBuild") - 专用编译
$FV_SPECIALBUILD ("SpecialBuild") - 特别编译
如果需要比较齐全的文件信息,看样子只能自己折腾,首先找出自己写的VBS脚本
ExplorerVer = GetProductVersion(SysWOW64Drive & "\Windows", "explorer.exe", "文件版本")
'********************************
'**
'** 读取文件扩展信息
'**
'********************************
Function GetProductVersion(Folder, FiLename, DetailsOf)
set objShell = CreateObject("shell.application")
set objFolder = objShell.NameSpace(lcase(Folder))
GetProductVersion = ""
ArrDetailsOf = Split(DetailsOf, "|")
Max_j = UBound(ArrDetailsOf)
For i = 0 to 300
For j=0 to Max_j
If objFolder.GetDetailsOf(objFolder.Items, i) = ArrDetailsOf(j) then
set objFolderItem = objFolder.ParseName(FiLename)
GetProductVersion = GetProductVersion & objFolder.GetDetailsOf(objFolderItem, i) & chr(13)
ArrDetailsOf(j) = ArrDetailsOf(Max_j)
Max_j = Max_j - 1
End If
Next
if Max_j < 0 then Exit For
Next
if GetProductVersion <> "" then GetProductVersion= Left(GetProductVersion, Len(GetProductVersion)-1)
End Function 'Function GetProductVersion
这个VBS脚本是利用信息类型获取文件对应信息
在转变为Au3代码时,硬是没把objFolder.GetDetailsOf(objFolder.Items, i) 写出来Au3对应的代码(真心脸红,我是个靠google来写代码的门外汉),幸好Au3交流群的一位大神(风过影相随)伸出援助之手
$sSourceFile = "U:\Au3\Patch\DFPHaiBaoW12-GB.TTF"
$sIndex = _GetFileDetailIndexByType($sSourceFile, "标题")
$sFileInfo = _GetFileDetailInfoByIndex($sSourceFile,$sIndex)
;// 利用信息类型获取文件对应信息的索引值
Func _GetFileDetailIndexByType($sFile, $sDetailType)
If FileExists($sFile) Then
Dim $f, $shell, $oParentShell, $oFile, $sInfoType
Local $sIndex = 0 ;//起始索引
$oFile = ObjCreate("Scripting.FileSystemObject")
$f = $oFile.GetFile($sFile) ;//返回文件对应的文件对象
$oParentShell = ObjCreate("Shell.Application")
$shell = $oParentShell.Namespace($f.ParentFolder.Path);ParentFolder......返回该文件夹
While 1
$sInfoType = $shell.GetDetailsOf(0, $sIndex) ;//文件的信息类型
If $sInfoType = '' Then ExitLoop ;//信息类型为空,跳出循环
If String($sInfoType) = String($sDetailType) Then
;//成功得到对应的索引值
$shell = 0
$oFile = 0
$oParentShell = 0
$f = 0
Return $sIndex
EndIf
$sIndex += 1 ;//索引值加1
WEnd
;//未获取对应的索引值
$shell = 0
$oFile = 0
$oParentShell = 0
$f = 0
Return SetError(2) ;//未获取对应的索引值
Else
;// 文件不存在
SetError(1)
EndIf
EndFunc ;==>_GetFileDetailIndexByType
;//利用索引值 获取文件对应索引下的 信息
Func _GetFileDetailInfoByIndex($sFile, $sIndex)
If FileExists($sFile) Then
Dim $f, $shell, $oParentShell, $oFile, $sDetailInfo
$oFile = ObjCreate("Scripting.FileSystemObject")
$f = $oFile.GetFile($sFile) ;//返回文件对应的文件对象
$oParentShell = ObjCreate("Shell.Application")
$shell = $oParentShell.Namespace($f.ParentFolder.Path);ParentFolder......返回该文件夹
$sDetailInfo = $shell.GetDetailsOf($shell.Items.Item($f.Name), $sIndex) ;//获取对应的信息
$shell = 0
$oFile = 0
$oParentShell = 0
$f = 0
Return $sDetailInfo
Else
;// 文件不存在
SetError(1)
EndIf
EndFunc ;==>_GetFileDetailInfoByIndex
最后在(风过影相随)代码基础上,重新写出了我自己需要的代码
$sSourceFile = "U:\Au3\Patch\DFPHaiBaoW12-GB.TTF"
$sFileInfo = _GetProductVersion($sSourceFile, "标题|类型")
$sFileInfo = _GetProductVersion($sSourceFile, "标题")
Func _GetProductVersion($sFile, $sDetailType)
Local $sDetailInfo = ""
If FileExists($sFile) Then
Dim $Path_, $Name_, $shell, $oParentShell, $sInfoType
Local $sIndex = 0
$Path_ = StringRegExpReplace($sFile, '(^.*)(\\.*$)', '$1')
$Name_ = StringRegExpReplace($sFile, '^.*\\', '')
$oParentShell = ObjCreate("Shell.Application")
$shell = $oParentShell.Namespace($Path_)
While 1
$sInfoType = $shell.GetDetailsOf(0, $sIndex)
If @error Then ExitLoop
If StringRegExp($sInfoType, $sDetailType) Then
$sDetailType = StringReplace($sDetailType, $sInfoType, "")
If @extended = 1 Then
$sDetailInfo = $sDetailInfo & $shell.GetDetailsOf($shell.Items.Item($Name_), $sIndex) & "|"
$sDetailType = StringTrimLeft($sDetailType, 1)
EndIf
EndIf
If $sDetailType = "" Then ExitLoop
$sIndex += 1
If $sIndex = 1000 Then ExitLoop
WEnd
EndIf
Return SetError(($sDetailInfo = "" ? 1 : 0), $sIndex, StringTrimRight($sDetailInfo, 1))
EndFunc ;==>_GetProductVersion
补正几点
一、需要查找的文件信息可以通过 | 分隔同时查找多个信息
$sFileInfo = _GetProductVersion($sSourceFile, "标题|类型")
二、我使用了二个正则来分离 目录 和 文件名
$Path_ = StringRegExpReplace($sFile, '(^.*)(\\.*$)', '$1')
$Name_ = StringRegExpReplace($sFile, '^.*\\', '')
三、由于设定了查询信息可以有多个,一般来说都会用二个循环来查询,一个循环枚举出所有信息,再套一个循环逐一检查是否匹配枚举出来的信息
由于设定了入口参数使用 | 分隔,这正好符合正则的代达方式,所以我干脆在这里换成了用正则的方法
If StringRegExp($sInfoType, $sDetailType) Then
StringRegExp($sInfoType, $sDetailType) ----> StringRegExp("程序标题", "标题|类型")
这样就简便了编程,不需要套用二个循环
但是由于这里使用的正则没有严谨匹配,如果查询到的信息是 "程序标题" "程序类型",那么也会匹配成功
为了纠正这种误判,接下来使用了
$sDetailType = StringReplace($sDetailType, $sInfoType, "")
If @extended = 1 Then
通过 StringReplace($sDetailType, $sInfoType, "") 可以把已经精确匹配到的条件过滤掉(注意一下这条语句和上面那条正则,二个参数的位置是互换了)
StringReplace($sDetailType, $sInfoType, "") ----> StringReplace( "标题|类型","程序标题","")
这样如果不是完全匹配的信息,@extended 将会是0,那么就可以防止误判了
整个程序写下来还有一个地方不满意,那么就循环的退出机制
If @error Then ExitLoop,事实上这句是没用的
全靠If $sIndex = 1000 Then ExitLoop来退出循环
有请路过的各位帮忙完善一下这里的循环退出机制
字体这个东西比较特殊,和dll,exe又不一样。如果你仅仅是想获取字体的名字,有现成的api:GetFontResourceInfo
#Include <WinAPIEx.au3>
Local $sFontFile = @ScriptDir & "\DFPHaiBaoW12-GB.TTF"
Local $sFontName = _WinAPI_GetFontResourceInfo($sFontFile, True)
ConsoleWrite($sFontName & @CRLF) 如果只是为了记录自己的学习心得,发到中文资料区更合适。
页:
[1]