Check right installation of 7-Zip (64 / 32bit) - vba

My goal is avoid error msg from VBA debugger. Need to check which version of 7-zip have installed, program files/ or program files (x86):
Trying do simple "IF" function.
Dim PathZipProgram As String
strCommand As String
PathZipProgram = "C:\Program Files(x86)\7-Zip\7z.exe"
If Right(PathZipProgram, 1) Then
PathZipProgram = PathZipProgram
Else
PathZipProgram = "C:\Program Files\7-Zip\7z.exe"
End If
Shell strCommand
strCommand = """" & PathZipProgram & """ a -tzip """
VBA cant find 7zip.

You can check if the file exist with a function like this:
Function FileExists(FilePath As String) As Boolean
Dim TestStr As String
TestStr = ""
On Error Resume Next
TestStr = Dir(FilePath)
On Error GoTo 0
If TestStr = "" Then
FileExists = False
Else
FileExists = True
End If
End Function
And then use it in your code:
Dim PathZipProgram As String
Dim strCommand As String
PathZipProgram = "C:\Program Files(x86)\7-Zip\7z.exe"
If Not FileExists(PathZipProgram) Then
PathZipProgram = "C:\Program Files\7-Zip\7z.exe"
End If
Shell strCommand
strCommand = """" & PathZipProgram & """ a -tzip """
Hope this help as a starting point.

Installation Path: 7-Zip could be installed in another disk location (for example the D: drive, or somewhere else). You do
need to read the paths from the registry to be sure. A couple of
suggestions below:
1. Hacky Version
I have put a full script below to use, but you can essentially get what you want the hacky way (make sure the paths actually exists - obviously - maybe use "C:\Program Files\7-Zip" if there are problems seen):
Check File Exists:
Set fso = CreateObject("Scripting.FileSystemObject")
If (fso.FileExists("C:\Program Files (x86)\7-Zip\7z.exe")) Then
' Do Stuff
End If
Get File Version:
Set fso = CreateObject("Scripting.FileSystemObject")
MsgBox fso.GetFileVersion("C:\Program Files (x86)\7-Zip\7z.exe")
Don't rely on this please. It will fail eventually. Please see below.
2. Full Version
Here is a full version, the steps you need to make something that has a hope to be reliable. Essentially read paths from registry and take it from there:
Const HKEY_LOCAL_MACHINE = &H80000002 : strComputer = "."
Set fso = CreateObject("Scripting.FileSystemObject")
Set reg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
' 64-bit - Read 7-zip installation path from registry
regpath64 = "SOFTWARE\7-Zip"
reg.GetStringValue HKEY_LOCAL_MACHINE, regpath64, "Path64", regvalue64
fullpath64 = regvalue64 + "\" + "7z.exe"
If (fso.FileExists(fullpath64)) Then
MsgBox "7-zip 64-bit: " + fso.GetFileVersion(fullpath64), vbOKOnly, "64-bit:"
End If
' 32-bit - Read 7-zip installation path from registry
regpath32 = "SOFTWARE\WOW6432Node\7-Zip"
reg.GetStringValue HKEY_LOCAL_MACHINE, regpath32, "Path", regvalue32
fullpath32 = regvalue32 + "\" + "7z.exe"
If (fso.FileExists(fullpath32)) Then
MsgBox "7-zip 32-bit: " + fso.GetFileVersion(fullpath32), vbOKOnly, "32-bit:"
End If
Disclaimer: For the 64-bit registry read: there could be a Path and a Path64 entry
(I have both). Not sure what earlier and / or later versions will
have. Please check.

Related

Issue while running exe from VBS script using Nsclient

I have written a vbs script for the intel cpu vulnerability which runs completely OK when I run it manually from command line or by double clicking it.
We have an NSClient/git infra across all servers which is used by nagios to create checks and I am trying to execute this script using NSClient++.exe from command prompt. However, when I run the file using NSClient it fails to create the log file(SA-00086--).
Here is my NSClient command from nsc.ini:
intel_cpu_vulnerability=C:\Windows\system32\cscript.exe //NoLogo //T:60 C:\WINDOWS\NSClient\scripts\DiscoveryTool\cpu-unsafe.vbs
Here is my cpu-unsafe.vbs Script:
' VB SCript to find the Intel Processor vulnerability.
Dim Maindir, objFSO, oFile, Executable, Vulnerable, NotVulnerable, objTextFile, Readme, VStatus, StatusLine, strLine
Const ForReading = 1
Maindir = "c:\Windows\nsclient\scripts\DiscoveryTool"
Executable = "Intel-SA-00086-console.exe"
Vulnerable = "Status: This system is vulnerable."
NotVulnerable = "Status: This system is not vulnerable."
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = WScript.CreateObject("WScript.Shell")
'Deleting all previous log/xml files
For Each oFile In objFSO.GetFolder(Maindir).Files
If LCase(objFSO.GetExtensionName(oFile.Name))= "log" or LCase(objFSO.GetExtensionName(oFile.Name)) = "xml" Then
If oFile.Name <> "CommandLine.xml" Then
Deleteme = Maindir+"\"+oFile
objFSO.DeleteFile oFile
End If
End If
next
'Running the Intel detector
WSHShell.Run Maindir + "\" + Executable , 0, True
Set objShell = Nothing
WScript.Sleep 3000
'Setting the logfile to read
For Each oFile In objFSO.GetFolder(Maindir).Files
If LCase(objFSO.GetExtensionName(oFile.Name))= "log" Then
If oFile.Name <> "CommandLine.xml" Then
Readme = oFile
End If
End If
next
Set objTextFile = objFSO.OpenTextFile(Readme, ForReading)
'Reading the logfile and determining if the prosessor is affected.
VStatus = "Undetermined"
do until objTextFile.AtEndOfStream
strLine = objTextFile.ReadLine()
If Left(strLine, 7) = "Status:" Then
If InStr(strLine, NotVulnerable) <> 0 then
VStatus = "OK"
StatusLine = strLine
End If
If InStr(strLine, Vulnerable) <> 0 then
VStatus = "NOK"
StatusLine = strLine
End If
End If
If Left(strLine, 24) = "Status: Detection Error:" Then
VStatus = "Undetermined"
StatusLine = strLine
End If
loop
'The FINAL RESULTS:
If VStatus = "OK" then
Wscript.Echo VStatus + ": Not Vulnerable -> From File: " + StatusLine
Wscript.Quit(1)
ElseIf VStatus = "NOK" then
Wscript.Echo VStatus + ": Vulnerable -> From File: " + StatusLine
Wscript.Quit(3)
Else
Wscript.Echo VStatus + ": May be Vulnerable -> From File: " + StatusLine
Wscript.Quit(2)
End If
objTextFile.Close
To test this script you have to download Windows Vulnerability Detection tool from Intel's Website. Once downloaded, extract the zip file and place this script inside DiscoveryTool Folder and run it by double clicking. The script will tell if your cpu is affected by the Intel® Management Engine vulnerability.
Edit: I further tried executing the .exe directly from the NSClient and it gave me Commandline.dll auth fail error.
nsc.ini command:
icvy=C:\WINDOWS\NSClient\scripts\DiscoveryTool\Intel-SA-00086-console.exe
Output:
l NSClient++.cpp(456) Enter command to inject or exit to terminate...
icvy
d NSClient++.cpp(1106) Injecting: icvy:
e \CheckExternalScripts.cpp(188) The command (C:\WINDOWS\NSClient\scripts\DiscoveryTool\Intel-SA-00086-console.exe) retu
rned an invalid return code: 11
d NSClient++.cpp(1142) Injected Result: WARNING 'Error: The file 'CommandLine.dll' authentication has failed.'
d NSClient++.cpp(1143) Injected Performance Result: ''
WARNING:Error: The file 'CommandLine.dll' authentication has failed.
Try setting the current working directory to the directory containing the executable. I was seeing the same error message until I did so. In VBScript, I gather that would look something like:
WSHShell.CurrentDirectory = Maindir
WSHShell.Run Maindir + "\" + Executable , 0, True

Find all the PDFs in a folder using Visual Basic in Access

So I am very new with using Visual Basic and I am having trouble. I want to open a folder and read all the PDFs in the folder for content. I found this code on the Microsoft Guidelines, but received errors regarding expectations of certain codes:
For Each foundFile As String In My.Computer.FileSystem.GetFiles(
My.Computer.FileSystem.SpecialDirectories.MyDocuments,
Microsoft.VisualBasic.FileIO.SearchOption.SearchAllSubDirectories, "*.pdf")
Listbox1.Items.Add(foundFile)
Next
Does anyone know why I am getting such errors?
See if this is useful
Sub Dougsloop()
Dim Filename As String
Dim path As String
path = "path to folder" & "\"
Filename = Dir(path & "*.pdf")
Do While Len(Filename) > 0
debug.print; FileName
'Listbox1.Items.AddItem (Filename) replace debug w/this
Filename = Dir
Loop
End Sub

Pass parameter\variable from .vbs to .bat

I'm trying to pass a variable from a VBS to BAT but i'm getting "The system cannot find the file specified"
Here is my vbs :
Option Explicit
Dim strFile
strFile = SelectFile( )
If strFile = "" Then
WScript.Echo "No file selected."
Else
WScript.Echo """" & strFile & """"
End If
Function SelectFile( )
Dim objExec, strMSHTA, wshShell
SelectFile = ""
strMSHTA = "mshta.exe ""about:" & "<" & "input type=file id=FILE>" _
& "<" & "script>FILE.click();new ActiveXObject('Scripting.FileSystemObject')" _
& ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);" & "<" & "/script>"""
Set wshShell = CreateObject( "WScript.Shell" )
Set objExec = wshShell.Exec( strMSHTA )
SelectFile = objExec.StdOut.ReadLine( )
Dim wshShelll
Set WshShelll = Wscript.CreateObject("WScript.Shell")
WshShelll.Run "C:\Users\nbendjelida\Desktop\email.bat" & SelectFile
Set objExec = Nothing
Set wshShell = Nothing
Set wshShelll = Nothing
End Function
here is my bat :
"C:\Program Files\Microsoft Office\Office12\Outlook.exe" /eml %1
do you have any idea ?
I repeat the right answer of sachadee with more details to get this question removed from the list of unanswered questions.
Run Method must be called with first parameter being the command to execute with the parameters exactly as when entering the command in the command line window. The examples on the referenced Microsoft help page have also a space character after the command Notepad.
The command line required to call the batch file with a file name as first parameter is:
C:\Users\nbendjelida\Desktop\email.bat name_of_selected_file
But the Windows script host code line
WshShelll.Run "C:\Users\nbendjelida\Desktop\email.bat" & SelectFile
builds the string for the command to run as
C:\Users\nbendjelida\Desktop\email.bat name_of_selected_file
because of the missing space character.
The problem is solved with the correct Windows script host code line
WshShelll.Run "C:\Users\nbendjelida\Desktop\email.bat " & SelectFile
because of the space charater between name of batch file and name of selected file.
If name of selected file contains 1 or more spaces, it is necessary that either variable SelectFile contains already a double quote at beginning and at end, or the necessary double quotes are added on concatenating the command string.
Example with entire batch file name also containing a space character:
Dim FileName
FileName = "%TEMP%\Any File.txt"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run """%USERPROFILE%\Desktop\My Batch File.bat"" """ & FileName & """"
The batch file My Batch File.bat on desktop of current user containing
#echo %0 %*
#pause
outputs for example on Windows 7
"C:\Users\username\Desktop\My Batch File.bat" "C:\User\username\AppData\Local\Temp\Any File.txt"
or on English Windows XP
"C:\Documents and Settings\user name\Desktop\My Batch File.bat" "C:\Documents and Settings\user name\Local Settings\Temp\Any File.txt"
which are the expected results for the command string.
(Yes, a user name can contain a space character although Microsoft recommends not to use a space character in user name, see Microsoft page Creating User and Group Accounts.)

VBScript to open a dialog to select a filepath

At present I am opening a file with my vbscript as follows:
strFile = "C:\Users\test\file.txt"
Set objFile = objFSO.OpenTextFile(strFile)
I would like to change this so that a file can be selected/navigated to by the user and that file is used in the script. How can I add this ability? I have tried to search for how to load a file dialog/prompt the user for a file etc just not sure how to complete in a VBScript.
There is another solution I found interesting from MS TechNet less customization but gets what you wanted to achieve. This returns the full path of the selected file.
Set wShell=CreateObject("WScript.Shell")
Set oExec=wShell.Exec("mshta.exe ""about:<input type=file id=FILE><script>FILE.click();new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);</script>""")
sFileSelected = oExec.StdOut.ReadLine
wscript.echo sFileSelected
Here you go:
http://www.robvanderwoude.com/vbstech_ui_fileopen.php
strFile = GetFileName("C:\Users\test\", "Text files|*.txt")
Set objFile = objFSO.OpenTextFile(strFile)
Function GetFileName( myDir, myFilter )
' Written by Rob van der Woude
' http://www.robvanderwoude.com
' Standard housekeeping
Dim objDialog
' Create a dialog object
Set objDialog = CreateObject( "UserAccounts.CommonDialog" )
' Check arguments and use defaults when necessary
If myDir = "" Then
' Default initial folder is "My Documents"
objDialog.InitialDir = CreateObject( "WScript.Shell" ).SpecialFolders( "MyDocuments" )
Else
' Use the specified initial folder
objDialog.InitialDir = myDir
End If
If myFilter = "" Then
' Default file filter is "All files"
objDialog.Filter = "All files|*.*"
Else
' Use the specified file filter
objDialog.Filter = myFilter
End If
' Open the dialog and return the selected file name
If objDialog.ShowOpen Then
GetFileName = objDialog.FileName
Else
GetFileName = ""
End If
End Function
The currently chosen answer doesn't support filters, but hta can be manipulated to support them.
Here's an answer based on this tek-tips.com post (which is also mentioned in
How to add filter to a file chooser in batch?), but I added a full function structure plus support for relative folders:
Function GetFileDlgEx(sIniDir,sFilter)
sTitle = "Choose File"
set objShell = WScript.CreateObject("WScript.Shell")
if instr(sIniDir, ":") <= 0 then
sIniDir = objShell.CurrentDirectory & "\" & sIniDir
end if
sIniDir = Replace(sIniDir,"\","\\")
Set oDlg = objShell.Exec("mshta.exe ""about:<object id=d classid=clsid:3050f4e1-98b5-11cf-bb82-00aa00bdce0b></object><script>moveTo(0,-9999);eval(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).Read("&Len(sIniDir)+Len(sFilter)+Len(sTitle)+41&"));function window.onload(){var p=/[^\0]*/;new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(p.exec(d.object.openfiledlg(iniDir,null,filter,title)));close();}</script><hta:application showintaskbar=no />""")
oDlg.StdIn.Write "var iniDir='" & sIniDir & "';var filter='" & sFilter & "';var title='" & sTitle & "';"
GetFileDlgEx = oDlg.StdOut.ReadAll
End Function
sIniDir = "*.*pdf" ' will look in current folder - note extension must be preceded by an asterisk *.
'sIniDir = "docs\*.*pdf" ' will look in a relative folder
'sIniDir = "C:\Windows\*.*pdf" ' will look in an absolute folder
sFilter = "Adobe pdf (*.pdf)|*.pdf|All files (*.*)|*.*|Microsoft Word (*.doc;*.docx)|*.doc;*.docx|Image files (*.gif;*.png;*jpg;*.bmp)|*.gif;*.png;*jpg;*.bmp|Html files (*.htm;*.html;*.mht)|*.htm;*.html;*.mht|"
rep = GetFileDlgEx(sIniDir,sFilter)
MsgBox rep
VBSEdit program installs a COM library VBSEdit Toolkit, which allows Open File dialogs.
From VBSEdit help:
Dialog boxes
OpenFileDialog method
Prompt the user to open a file
toolkit.OpenFileDialog ([initialFolder,[filters,[multiselect,[title]]]])
'Opens a single file
Set toolkit = CreateObject("VbsEdit.Toolkit")
files=toolkit.OpenFileDialog("c:\scripts\","Text Files (*.txt)|*.txt",False,"Open a text file")
If UBound(files)>=0 Then
WScript.Echo files(0)
Else
Wscript.Quit
End If
'Opens multiple files
Set toolkit = CreateObject("VbsEdit.Toolkit")
files=toolkit.OpenFileDialog("c:\scripts\","Text Files (*.txt)|*.txt",True,"Open a text file")
If UBound(files)>=0 Then
For Each filepath In files
WScript.Echo filepath
Next
Else
Wscript.Quit
End If
SaveFileDialog method
Prompt the user to save a file
toolkit.SaveFileDialog ([initialFolder,[initialFilename,[filters,[title]]]])
Set toolkit = CreateObject("VbsEdit.Toolkit")
filepath = toolkit.SaveFileDialog("c:\scripts","test.txt","Text Files (*.txt)|*.txt")
If Not(IsNull(filepath)) Then
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.CreateTextFile(filepath,True)
objFile.WriteLine Date
objFile.Close
Else
Wscript.Quit
End If
SelectFolder method
Prompt the user to select a folder
toolkit.SelectFolder ([initialDir,[title]])
Set toolkit = CreateObject("VbsEdit.Toolkit")
myfolder=toolkit.SelectFolder("c:\scripts\","Please select a folder")
If Not(IsNull(myfolder)) Then
WScript.Echo myfolder
Else
Wscript.Quit
End If
…
(Actually, folder selection dialogs can be opened without VBSEdit toolkit, with BrowseForFolder method of Shell.Application object.)
Found this answer HERE
Set WshShell=CreateObject("Wscript.Shell")
WshShell.BrowseForFolder(0, "Please select the folder.", 1, "")

Finding txt File path dynamically

I need to read a txt file but I don't have the path. The text file is two directories before the path of the script I'm running. I thought I could use "WScript.ScriptFullName" and then just use an instrRev and make it split the str at "/". But It doesn't work Could you guys help me with that. I have to run this on multiple computers so the path changes but the text file will always be two derictories above the script path
My code so far
Dim strScriptPath
strScriptPath = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
WScript.Echo strScriptPath
WScript.Echo(WScript.ScriptFullName)
Dim DashRev
DashRev = instrRev(WScript.ScriptFullName, "/")
wscript.echo DashRev
First replace the "/" with "\"
Then try the following. This seems to work for me:
Dim strScriptPath
strScriptPath = Replace(WScript.ScriptFullName, WScript.ScriptName, "")
WScript.Echo strScriptPath
WScript.Echo(WScript.ScriptFullName)
Dim first, sec
first = instrRev(strScriptPath, "\",Len(strScriptPath)-1)
sec = instrRev(WScript.ScriptFullName, "\",first-1)
wscript.Echo "parent = " & Left(strScriptPath,sec)
The idea being that strScriptPath is always going to end in "\" and first is going to exclude that from the instrrev by using the starting position of one less than the length of the path. Same thing essentially with sec.
Set FSO = WScript.CreateObject("Scripting.FileSystemObject")
WScript.Echo FSO.GetFile(WScript.ScriptFullName).ParentFolder.ParentFolder.ParentFolder.Path