I would like to write a script that can recursively scan the DLLs in a directory and generate a report of all of their version numbers.
How can I detect the version number of a DLL using a script? VBScript solutions are preferred, unless there is a better way.
You can use the FileSystemObject object to access the file system and its GetFileVersion method to obtain the file version information.
You asked for a VBScript example, so here you are:
Dim oFSO : Set oFSO = CreateObject("Scripting.FileSystemObject")
PrintDLLVersions oFSO.GetFolder(WScript.Arguments.Item(0))
Sub PrintDLLVersions(Folder)
Dim oFile, oSubFolder
' Scan the DLLs in the Folder
For Each oFile In Folder.Files
If UCase(oFSO.GetExtensionName(oFile)) = "DLL" Then
WScript.Echo oFile.Path & vbTab & oFSO.GetFileVersion(oFile)
End If
Next
' Scan the Folder's subfolders
For Each oSubFolder In Folder.SubFolders
PrintDLLVersions oSubFolder
Next
End Sub
Usage:
> cscript //nologo script-file.vbs folder > out-file
e.g.:
> cscript //nologo dll-list.vbs C:\Dir > dll-list.txt
Sample output:
C:\Dir\foo.dll 1.0.0.1
C:\Dir\bar.dll 1.1.0.0
C:\Dir\SubDir\foobar.dll 4.2.0.0
...
EDIT I think this is the source I referenced
This is the script that I use, I apologize, but I don't recall from where. (So,reader, if this started as your script please step forward) It uses the FileSystemObject which can get version directly.
#echo off
setlocal
set vbs="%temp%\filever.vbs"
set file=%1
echo Set oFSO = CreateObject("Scripting.FileSystemObject") >%vbs%
echo WScript.Echo oFSO.GetFileVersion(WScript.Arguments.Item(0)) >>%vbs%
for /f "tokens=*" %%a in (
'cscript.exe //Nologo %vbs% %file%') do set filever=%%a
del %vbs%
echo Full file version of %file% is: %filever%
for /f "tokens=2 delims=. " %%a in ("%filever%") do set secondparam=%%a
set splevel=%secondparam:~0,1%
echo SP level is: %splevel%
endlocal
pause
Related
I use the following function in a lot of my VBA projects. I initially added the reference to Windows Script Host Object model to take advantage of Intellisense, but then switched to late binding so I didn't have to reference a bunch of stuff.
Private Function RunCMD(ByVal strCMD As String) As String
'Runs the provided command
Dim oShell As Object 'New WshShell
Dim cmd As Object 'WshExec
Dim x As Integer
Const WshRunning = 0
On Error GoTo wshError
x = 0
RunCMD = "Error"
Set oShell = CreateObject("Wscript.Shell")
Set cmd = oShell.Exec(strCMD)
'Debug.Print strCMD
'Stop
Do While cmd.Status = WshRunning
Sleep 100 'for 1/10th of a second
x = x + 1
If x > 1200 Then 'We've waited 2 minutes so kill it
cmd.Terminate
MsgBox "Error: Timed Out", vbCritical, "Timed Out"
End If
Loop
RunCMD = cmd.StdOut.ReadAll & cmd.StdErr.ReadAll
Set oShell = Nothing
Set cmd = Nothing
Exit Function
wshError:
On Error Resume Next
RunCMD = cmd.StdErr.ReadAll
Resume Next
End Function
It works great when you do something like
RunCMD("ping www.bing.com") or
RunCMD("winrs -r:" & strHost & " reg query hklm\system\currentcontrolset\services\cdrom /v start")
However RunCMD("Dir c:\config* /a:-d /b /d /s") fails, and cmd.StdErr.ReadAll gives an Object Variable or With Block not set error. Even a simple RunCMD("Dir") fails.
Why does DIR make the WScript shell crap out? More importantly, how can I use CMD's DIR function (not VBA's DIR function!) to get a list of files that match a search pattern?
Does it work if you preface your dir command with "cmd /c " and wrap your DOS command in double quotes, like
RunCmd("cmd /c ""DIR""")
or
RunCmd("cmd /c ""Dir c:\config* /a:-d /b /d /s""")
I need use vbscript to delete some browser files.
I have simple batch code like
del /q /s /f "C:\Users\%USERNAME%\AppData\Roaming\Opera Software\Opera Stable\Current Session"
rd /s /q "C:\Users\%USERNAME%\AppData\Roaming\Opera Software\Opera Stable\Current Session"
In vbs
Set obj = CreateObject("Scripting.FileSystemObject")
obj.DeleteFile("C:\Users\%USERNAME%\AppData\Roaming\Opera Software\Opera Stable\Current Session")
Problem is that vbs doesn't recognize variable %USERNAME% and I am getting error "no file in this directory".
Could someone tell me how to write variable directory/path in this language?
From Help.
Returns an environment variable's expanded value.
object.ExpandEnvironmentStrings(strString)
imageArguments
object
WshShell object.
strString
String value indicating the name of the environment variable you want to expand.
Remarks
The ExpandEnvironmentStrings method expands environment variables defined in the PROCESS environment space only. Environment variable names, which must be enclosed between "%" characters, are not case-sensitive.
imageExample
The following code expands the Windows Directory environment variable and displays it:
Visual Basic Script
set WshShell = WScript.CreateObject("WScript.Shell")
WScript.Echo "WinDir is " & WshShell.ExpandEnvironmentStrings("%WinDir%")
If you want to do it in vbs you use recursion.
On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
ProcessFolder "c:\users\david candy\documents"
Sub ProcessFolder(FolderPath)
Set fldr = fso.GetFolder(FolderPath)
Set Fls = fldr.files
For Each thing in Fls
wscript.echo thing.path
Next
Set fldrs = fldr.subfolders
For Each thing in fldrs
' wscript.echo thing.name
ProcessFolder thing.path
Next
End Sub
You can try :
Set objFSO = CreateObject("Scripting.FileSystemObject")
set WshShell = CreateObject("WScript.Shell")
UserProfile = WshShell.ExpandEnvironmentStrings("%USERPROFILE%")
Wscript.echo UserProfile
Wscript.echo UserProfile &"\AppData\Roaming\Opera Software\Opera Stable\Current Session"
AppData = WshShell.ExpandEnvironmentStrings("%AppData%")
Wscript.echo AppData
Wscript.echo AppData &"\Opera Software\Opera Stable\Current Session"
If objFSO.FolderExists(AppData &"\Opera Software\Opera Stable\Current Session") Then
objFSO.DeleteFolder AppData &"\Opera Software\Opera Stable\Current Session"
End If
I am using the following code (as found here) in Word2010 to find the target path of a shortcut:
Function Getlnkpath(ByVal Lnk As String)
On Error Resume Next
With CreateObject("Wscript.Shell").CreateShortcut(Lnk)
Getlnkpath = .TargetPath
.Close
End With
End Function
Sub GetLinkPath()
MsgBox Getlnkpath("yourshortcutnamehere")
End Sub
When I run the code as shown (modified to use my shortcut name) I get the following error:
Run-time error '438':
Object doesn't support this property or method
and the .Close line is highlighted for debug. When I comment out .Close the script works fine.
Does this cause problems if the shell doesn't close? I've read that .Close isn't necessary for Wscript.Shell but can't confirm that.
There is no Close method to the shortcut object and that is why you are getting the error. This link lists basic operations of WScript.Shell.
If you are intending to dispose the shell object, the best way to do would be
Set objWshShell = WScript.CreateObject("WScript.Shell")
With objWshShell.CreateShortcut(Lnk)
.Save
Getlnkpath = .TargetPath
End With
Set objWshShell = Nothing
Posting this answer for anyone who is still stuck on trying to close the WScript.Shell Object after creating it and not able to find a solution.
My Vb Script :
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell", vbNothing)
wsh.Run "cmd.exe /C pause"
wsh.Run "taskkill /F /IM cmd.exe"
currently i have an Email that comes in and my vba code will save the file to a folder, however since this code was made they now send me the file in a zip file. This of course breaks the code and i have to resend it in a non zip file to make it work. Here is a sample of what I am currently using:
If Left(objItem.Subject, 28) = "xxxxx report Toolbox" Then
For Each Atmt In objItem.Attachments
FileName = "O:\Automated Reports\toolbox.xlsx"
Atmt.SaveAsFile FileName
modify_file
Debug.Print "success CSAT file"
Open "O:\Automated Reports\toolboxDate.JW" For Output As #1
Write #1, Right(objItem.Subject, 5)
Close #1
Next Atmt
End If
As i stated before this code woks fine for just saving the file when it is not a .zip file. I need it to unzip the file and save it to the O: drive. I have tried to use some shell.application objects but i didn't quite get that to work. Thanks for any help ahead of time
'Create new blank zip.
Set Ag=Wscript.Arguments
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.OpenTextFile(Ag(0), 8, vbtrue)
BlankZip = "PK" & Chr(5) & Chr(6)
For x = 0 to 17
BlankZip = BlankZip & Chr(0)
Next
ts.Write BlankZip
'Unzip
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set SrcFldr=objShell.NameSpace(Ag(1))
Set DestFldr=objShell.NameSpace(Ag(0))
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Msgbox "Finished"
'Zip
Set objShell = CreateObject("Shell.Application")
Set Ag=Wscript.Arguments
set WshShell = WScript.CreateObject("WScript.Shell")
Set DestFldr=objShell.NameSpace(Ag(1))
Set SrcFldr=objShell.NameSpace(Ag(0))
Set FldrItems=SrcFldr.Items
DestFldr.CopyHere FldrItems, &H214
Msgbox "Finished"
I created a temporary folder that gets deleted later on in the program using this code:
'Creates a new temporary directory path for a folder copy
If dir("C:\\InventorTempFolder\\\", vbDirectory) = "" Then
MkDir "C:\\InventorTempFolder\\\"
SetAttr "C:\InventorTempFolder", vbNormal
Else: MsgBox "This folder already exists."
End If
(I don't know if the SetAttr is right...that's part of my question!)
I then pulled this code offline that should delete all the files and directories in this folder, using this code:
Sub DeleteDirectory()
Dim dir_name As String
Dim file_name As String
Dim files As Collection
Dim i As Integer
dir_name = "C:\\InventorTempFolder"
' Get a list of files it contains.
Set files = New Collection
file_name = dir$(dir_name & "\*.*", vbReadOnly + _
vbHidden + vbSystem + vbDirectory)
Do While Len(file_name) > 0
If (file_name <> "..") And (file_name <> ".") Then
files.Add dir_name & "\" & file_name
End If
file_name = dir$()
Loop
' Delete the files.
For i = 1 To files.Count
file_name = files(i)
' See if it is a directory.
If GetAttr(file_name) = vbDirectory Then
Kill file_name
Else: Kill file_name
End If
Next i
' The directory is now empty. Delete it.
RmDir dir_name
' Remove the read-only flag if set.
' (Thanks to Ralf Wolter.)
End Sub
However, the directory won't delete. My theory is that it is because the directory is a read-only folder. That is why I tried to change the attribute to vbNormal, but it won't change. So questions I'm wondering is:
Why won't it delete? Is my theory right that it is because it is read-only?
If so, how can I fix that?
If not, what else is wrong...?
Thanks ahead of time!
The end of your script is:
RmDir dir_name
' Remove the read-only flag if set.
' (Thanks to Ralf Wolter.)
RmDir dir_name
So you're attempting to remove the same directory twice. And dir_name at this point is set to the "SillyVBA" directory -- this did get deleted when I tested it. I'm assuming the second RmDir is meant to delete "C:\InventorTempFolder"; that also worked for me when I tested it.
Updated in response to comment
The problem is likely due to your attempt to use Kill when the file type is a directory. To do a full recursive delete, you would need to start at the bottom of the tree, deleting all files and empty directories as you work your way up. However a much easier way is to use FileSystemObject:
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
fso.deletefolder dir_name
This will delete the directory and everything in it, in one shot.