返回列表 发帖

[原创] vbs脚本调用wmi将文件重命名为文件修改时间(精确到秒)

如需转载请注明出处:
http://www.bathome.net/thread-15803-1-1.html
'vbs脚本调用wmi将文件重命名为文件修改时间(精确到秒)
'By powerbat @ www.bathome.net 批处理之家 vbs脚本调用wmi
Dim strFolder, strType, SubDir
Dim strComputer, objWMIService, fso, strFilter
strFolder = "r:\jpg" '文件所在目录
strType = "bmp,jpg,png" '文件类型
SubDir = 0 '是否包含子目录
if (WScript.Arguments.Length) then strFolder = WScript.Arguments(0)
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
Set fso = CreateObject("Scripting.FileSystemObject")
strFilter = ""
if (strType<>"*" AND strType<>"*.*") then
  strFilter = " AND (Extension='" _
    & Replace(strType, ",", "' OR Extension='") & "')"
end if
EnumViaWMI strFolder
rem 为什么不直接用fso遍历文件?因为fso有着与cmd的for相同的bug:
rem 遍历过程中如果文件名有变动,会造成重复遍历。(循环被扰乱?)
Sub EnumViaWMI(strFolder)
  Dim strQuery, colFiles, objFile, colFolders, objFolder
  Dim strName, strExtension, strTime, n, strTail, strSuffix
  'WScript.Echo(strFolder)
  strQuery = "SELECT * FROM CIM_DataFile " _
    & " WHERE (Drive='" & Left(strFolder, 2) & "' " _
    & " AND Path='" & Replace(Mid(strFolder, 3), "\", "\\") & "\\' " _
    & strFilter & ")"
  '这次重命名目的:当文件修改时间相同且新文件名可能已存在时,编号可以连续。
  if 0 then
    Set colFiles = objWMIService.ExecQuery(strQuery, , 48)
    For Each objFile in colFiles
      strName = objFile.FileName & "." & objFile.Extension
      n = Empty
      do while 10 = objFile.Rename(strFolder & "\" _
          & "powerbat@bathome" & n & "_" & strName)
        n = n + 1
      loop
    Next
  end if
  Set colFiles = objWMIService.ExecQuery(strQuery, , 48)
  For Each objFile in colFiles
    'WScript.Echo objFile.Name
    strExtension = objFile.Extension
    strTime = MyTime(objFile.LastModified)
    n = Empty : strTail = Empty
    if objFile.FileName <> strTime then
      '返回码为10表示文件已存在
      'do while 10 = objFile.Rename(strFolder & "\" _
      '    & strTime & strTail & "." & strExtension)
      '  n = n + 1 : strTail = "_" & n
      'loop
      rem WMI 判断文件是否已存在效率太低了,借用fso
      do while fso.FileExists(strFolder & "\" _
          & strTime & strTail & "." & strExtension)
        n = n + 1 : strTail = "_" & n
      loop
    end if
    objFile.Rename(strFolder & "\" & strTime & strTail & "." & strExtension)
  Next
  if (Not SubDir) then Exit Sub
  Set colFolders = objWMIService.ExecQuery( _
    "ASSOCIATORS OF {Win32_Directory='" & strFolder & "'} WHERE " _
    & " AssocClass = Win32_SubDirectory ResultRole = PartComponent", , 48)
  For Each objFolder in colFolders
    EnumViaWMI objFolder.Name
  Next
End Sub
function MyTime(DateTime)
MyTime = Left(DateTime, 4) & "-" _
    & Mid(DateTime, 5, 2) & "-" _
    & Mid(DateTime, 7, 2) & " " _
    & Mid(DateTime, 9, 2) & "." _
    & Mid(DateTime, 11, 2) & "." _
    & Mid(DateTime, 13, 2)
end functionCOPY
1

评分人数

rem 为什么不直接用fso遍历文件?因为fso有着与cmd的for相同的bug:
rem 遍历过程中如果文件名有变动,会造成重复遍历。(循环被扰乱?)

我经常用fso重命名文件,为啥没碰到过?

TOP

至少XP绝对是有这个bug的。可能后来的系统修正了。
strFolder = "D:\jpg"
Set fso = CreateObject("Scripting.FileSystemObject")
Set fc = fso.GetFolder(strFolder).Files
n = 0
for each f in fc
    if InStr(1, Right(f.name,3), "jpg", 1) then
        wsh.echo f.path
        n = n + 1
        f.name = n & "_" & f.name
    end if
nextCOPY
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>md D:\jpg

C:\Documents and Settings\Administrator>cd /d D:\jpg

D:\jpg>for /l %a in (1 1 11) do @cd.>%a.jpg

D:\jpg>cscript D:\fsoren.vbs
D:\jpg\1.jpg
D:\jpg\10.jpg
D:\jpg\11.jpg
D:\jpg\1_1.jpg
D:\jpg\2.jpg
D:\jpg\3.jpg
D:\jpg\4.jpg
D:\jpg\5.jpg
D:\jpg\6.jpg
D:\jpg\7.jpg
D:\jpg\8.jpg
D:\jpg\9.jpg

D:\jpg>

和cmd一样,这个bug不是必现的,还没找到规律。

TOP

返回列表