I've been working on a way to quickly and easily list all of the software installed on my machine. Once complete, I'd like to send it out to my group so that I can have everyone run it. Since the purpose of this exercise is generate a list of all of the applications that we absolutely require access to to our IT administrators, I don't want to miss anything important.
Up to this point, I've used code very similar to this - it looks in the registry at SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ and Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ and gives me all of the software that has been installed. However, a bunch of important programs are conspicuously absent (e.g. R, RStudio, SQL Developer), and I assume it's because they do not use Windows Installers.
This brings me to my question - is there a way I can list all of the programs that can be run on my machine (that have not impacted the registry)? Essentially, I think I want all of the non-system *.exe files, but that is probably oversimplifying things.
Anyone have any ideas? My code is VBS now, but I can muddle my way through most things.
If you want to find them all then you need to search every single file on your machine and check whether or not it has an executable extension. I'm reasonably confident that you are not going to want to do this.
I read your answer and laughed, since I was also "reasonably confident" that I did not want to go through all of the files on my (or anyone else's) machine. Once the laughing stopped, I realized that that's essentially what I had to do...
I've come up with something that works, and it now takes minutes to run (it took seconds to only check the registry), but it does work. I'm putting it here in case it can assist someone else, or maybe someone can find a way to make it more efficient. You need to supply some paths to folders where you want to look for exe files, and a file that you want to output to.
Thanks for reading.
On Error Resume Next
Folders = Array("C:\users\me","C:\SoftwareFolder1","C:\SoftwareFolder2","C:\SoftwareFolder3")
sFile="C:\myExeFiles.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Const ForWriting = 2
Const OverwriteIfExist = -1
Set fFile = objFSO.CreateTextFile(sFile, OverwriteIfExist, OpenAsASCII)
For Each x In Folders
Set objFolder = objFSO.GetFolder(x)
suckTheData objFSO, fFile, objFolder
Set objFolder = Nothing
Next
MsgBox("Done")
Set objFSO = Nothing
Sub suckTheData(objFSO, fFile, objFolder)
' *** STEP 1 *** 'Find files with a partiular extension in this folder
For Each objFile In objFolder.Files
If UCase(objFSO.GetExtensionName(objFile.Name))="EXE" Then
fFile.Write objFile & vbCrLf
If Err.Number <> 0 Then
fFile.Write "Error: " & objFile & " " & Err.Number & Err.Source & " " & Err.Description & vbCrLf
End If
End If
Next
Set objFile = Nothing
' *** STEP 2 *** 'Now that we've processed files, repeat for subdirectories
For Each subf In objFolder.SubFolders
'some folders can't/shouldn't be checked -
'16 is a normal folder, 32 is an archive, 1046 is symbolic, etc
If subf.Attributes ="16" Then
suckTheData objFSO, fFile, subf
End If
Next
Set subf = Nothing
End Sub
Related
I'm having a strange problem with VBScript. I'd like to implement some other code with a following test:
If there is a file named like [that] in the [folder], do not copy it into the [folder].
Thing is, I found a strange relation in oFS.FileExists, I'm able to use it in a manually created folder, as long as I manually copy and paste a file into it. Then oFS.FileExists works like a charm.
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
filestr = "C:\where\file\is\file.file"
If (oFS.FileExists(filestr)) Then
WScript.Echo("File exists!")
WScript.Quit()
Else
WScript.Echo("File does not exist!")
End If
But it's not exactly my point. I'd like to test if a file is already in the desired folder, and such folder will be generated automatically with oFS.CreateFolder. But when it comes to testing an automatically generated folder, it's a different story.
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
oFS.CreateFolder(destination & objFoldername)
Initially I thought it might be something wrong with the file I'm looking for. I moved it to some other place and the oFS.FileExists found it. So I figured it might be the case of the folder itself. I can see the folder is a Read Only folder. I tested it in other manually created Read Only folder, also found it.
Finally I manually created the folder exactly like oFS.CreateFolder would do it, pasted manually a file into it and... it also found a file just fine.
As I witnessed, every test I conduct in a generated folder is failed, but done in a manually created one, pass.
Remarkable!
Had anyone such a case? Do you know why oFS.FileExists puts a blind eye on something created itself?
I'm using 64-bit Windows 10 Home, and I wrote both scrips in Visual Studio Code if that would be relevant.
Cheers guys, I can't be the first one.
EDIT for leeharvey1
Thank you leeharvey1 that you took a minute to have a look at this. This is the code that creates the directories:
Dim oFS, oFile, objShell, objFolder, sFolderPathspec, destination, file
Set oFS = CreateObject("Scripting.FileSystemObject")
sFolderPathspec = "C:\folder\where\files\are\"
Set objShell = CreateObject ("Shell.Application")
destination = "C:\folder\where\new\folders\with\files\are\intended\to\be\"
Set objFolder = objShell.Namespace(sFolderPathspec)
For Each file In objFolder.Items
name = file.Name
wykonano = objFolder.GetDetailsOf(file, 12)
If wykonano = "" Then
wykonano = objFolder.GetDetailsOf(file, 3)
End If
arr = Split(wykonano, " ")
brr = Split(arr(0), "-")
rok = brr(0)
miesiac = brr(1)
objFoldername = rok & "-" & miesiac
If CStr(oFS.FolderExists(destination & objFoldername)) >< "Prawda" Then
oFS.CreateFolder(destination & objFoldername)
End If
newdestination = destination & objFoldername & "\" & name
oFS.CopyFile sFolderPathspec & name, newdestination, False
Next
The whole testing for file existence started because I could not have the following to run:
oFS.CopyFile sFolderPathspec & name, newdestination, False
I would love it to copy but not overwrite. False, is however syntax correct, opposing to "Fałsz" (which would be correct in my Windows language). But the code crashes as soon as it hits the file that is already in the destination folder. Maybe should I have some kind of code which will let the sequence of code continue over the crashes caused by already existing files? (Like Python has)
So it took me to the following problem of testing for existence.
I figured I'll use the following method of the Files collection. As mentioned above, I get fails every time I conduct a test in generated folder, but done in a manually created one, pass.
That's the code (so far in a different VBScript file):
filestr = "C:\where\file\is\file.file"
Dim oFS
Set oFS = CreateObject("Scripting.FileSystemObject")
If oFS.FileExists(filestr) Then
MsgBox("Jest plik")
Else
MsgBox("Nie ma pliku")
End If
Function FileExists(FilePath)
Set oFS = CreateObject("Scripting.FileSystemObject")
If oFS.FileExists(FilePath) Then
FileExists=CBool(1)
Else
FileExists=CBool(0)
End If
End Function
If FileExists(filestr) Then
WScript.Echo "Does Exist"
Else
WScript.Echo "Does not exist"
End If
If (oFS.FileExists(filestr)) Then
WScript.Echo("File exists!")
WScript.Quit()
Else
WScript.Echo("File does not exist!")
End If
So, there are some details you wanted to know:
No, I am not working against a network shared file. It's all locally on my PC's ssd.
Have you tried disabling your anti-virus? No, if I'll need to do so in order to use it, I don't need the code.
I think I need to look for a file not for a folder, there is some kind of problem to locate the file. Do you think there could be also a problem to locate the folder itself?
Check folder Owner. Well, as far as I can see in Windows folder properties, it looks and have just the same settings as any other folder over there.
Thanks again leeharvey1 for your time!
The IT company I work for has requested me to make a script that would be able to download the needed files and store them, in a folder for a later install.
This is the code I used
Set BS = CreateObject("ADODB.Stream")
BS.type = 1
BS.open
BS.Write xHttp.ResponseBody
BS.savetofile "putty.exe", 2 '//overwrite
If objFileSys.FileExists("putty.exe") Then
objFileSys.DeleteFile "putty.exe"
BS.SaveToFile "putty.exe", 2
Set objFile = objFso.GetFile("putty.exe")
'* If the file doesn't exist, it will be downloaded here.
Else
BS.SaveToFile "putty.exe", 2
Set objFile = objFso.GetFile("putty.exe")
End If
This code ^ has no issues, however, this code does:
Set BS = CreateObject("ADODB.Stream")
BS.type = 1
BS.open
BS.Write xHttp.ResponseBody
' If the file does exist, it will be deleted and re-downloaded.
If objFileSys.FileExists("" + strDirectory + "\putty.exe") Then
objFileSys.DeleteFile "" + strDirectory + "\putty.exe"
BS.SaveToFile "" + strDirectory + "\putty.exe", 2
Set objFile = objFso.GetFile("" + strDirectory + "\putty.exe")
' If the file doesn't exist, it will be downloaded here.
Else
BS.SaveToFile "" + strDirectory + "\putty.exe", 2
Set objFile = objFso.GetFile("" + strDirectory + "\putty.exe")
End If
For some reason the antivirus (sophos) flags the second code, but I'm unsure why?
The first code as you can see will just download the file and save it to were the .vbs is, the issue with this the company did not like that. I tried to put the files in C: but you need admin rights, which means you need to login as admin (ugh).
So I made the script just put all the needed files into a temp folder, "strDirectory" goes to "C:\Users\NAME\AppData\Roaming\Work" the reason I did this was because then the script would collect the PC's username i.e. Bob and so it would go to "C:\Users\Bob\AppData\Roaming\Work" example:
"C:\Users\"+ PC NAME+ "\AppData\Roaming\Work"
But again the antivirus flags and I'm not sure why?
Thanks!
PS This is not my script I found it here on stackoverflow, I have just edited it to fit my needs.
PSS I cannot upload the full code for company issues, but the error is in the download part.
The two scripts are similar but just a small change can make a big difference.
The first is constricted to saving the executable file in the location where the script has been executed from.
The second isn't constricted and can theoretically save the executable anywhere on the target machine (dependent on local security, execution rights of the script etc.).
This is a potential red flag for AntiVirus Software packages and the likely cause of the second script being flagged. The only suggestion without removing the AntiVirus (which I wouldn't recommend) would be to whitelist the script if supported in the package.
Usually, in corporate networks, AntiVirus is handled centrally, so there is potentially a way of whitelisting the script from a central admin portal but you would need to speak to your IT Infrastructure Team to facilitate it.
I'm trying to use VBScript to examine the contents of several hundred .zip files. Essentially what I want to do is run through each .zip and find all of the files wihtin that zip file. For each one of these files within the zip, I want to record some information about it to an Oracle database. That information being: file name and file modified date.
So far, my solution has been extracting each zips folder structure to a temp folder then running through the temp folder with an fso object. However, this has been proven to be very slow.
Is there a way to accoplish this without unziping the zip files?
Ouch man. I have never heard of vbscript zip object. But it has been a long time since I have done vbscript. Is there anyway you can avoid it?
I did some googling for you. I did find this: http://www.example-code.com/vbscript/zip_List.asp Chilkat has done a lot of stuff I thought not possible. This gives me the impression - that what you are trying to do is not going to be painless.
If given the problem you have I would find a different solution than vbscript. But if you pull-it-off I would vote for you to be mayor of vb land
You can do it in place with Shell Objects. But it will be just as slow, maybe. If just name and date Explorer may get it direct from the zip directory (at the end of the file so the whole file still needs to be read).
This copies items in a folder to another folder. A zip file is a folder so it will copy in and copy out.
To Zip
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"
To Unzip (note SrcFolder and DestFolder are reversed)
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"
To Create a blank zip. (I should have used an ADODB binary stream rather than an FSO text stream, but it shouldn't matter)
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
I have this script I use to compress a copy of my files to a network drive. The Processing dialog shows the files being copied and I've noticed the process seems to go through files really fast at first, but then slows way down for the last 20% or so (judging by the progress bar). I've noticed this on both W7 32 and 64 bit. Some text files that are only a few K may take a minute or two.
Is this normal, or is there something in my script might be causing the slow-down?
'Target directory
ZipFile = "Z:\MyDocsBU\MyDocsBackup_" & Right("0" & DatePart("m",Now()),2) & Right("0" & DatePart("d",Now()),2) & DatePart("yyyy",Now()) & ".zip"
'Check for source folder on file
set filesys = CreateObject("Scripting.FileSystemObject")
If filesys.FileExists("Z:\MyDocsBU\SourceFolder.txt") Then
set objFileToRead = CreateObject("Scripting.FileSystemObject").OpenTextFile("z:\MyDocsBU\SourceFolder.txt", 1, true)
setDirectory = objFileToRead.ReadAll()
objFileToRead.Close
Set objFileToRead = Nothing
SourceFolder = InputBox("You are about to back up:", "Source Folder", setDirectory)
Else
'Source directory with user input first time only
Set objFileToWrite = CreateObject("Scripting.FileSystemObject").OpenTextFile("Z:\MyDocsBU\SourceFolder.txt",2,true)
SourceFolder = InputBox("Please enter the folder directory to back up." & vbCrLf & vbCrLf & "Example:" & vbCrLf & "C:\Users\your.name\Documents", "Source Folder", "C:\Users\")
If SourceFolder = "" Then
Wscript.Quit
Else
objFileToWrite.Write(SourceFolder)
objFileToWrite.close
End If
End If
Const FOF_CREATEPROGRESSDLG = &H0&
' Create empty ZIP file and open for adding
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set zip = CreateObject("Shell.Application").NameSpace(ZipFile)
' Get items in source folder
Set sourceItems = CreateObject("Shell.Application").NameSpace(SourceFolder).Items
' Add all files/directories to the .zip file and show progress bar
zip.CopyHere(sourceItems), FOF_CREATEPROGRESSDLG
'Wait for items to be copied, hides behind progress bar
wscript.echo "Wait until progress bar closes before clicking OK."
This is probably due to write caching. Windows buffers the files into memory first and then to the target destination from there. The main benefit of this is that if an application waits on the file write it gets notified earlier and can continue.
If the target drive is a lot slower in writing than the source is in reading in windows 7 this will lead to the behaviour you described. Normally the files are copied with a speed much higher than technically possible at the beginning (200MB/s to USB 2.0 drives etc). The progress bar is based on the total amount of data copied so the gains will be huge at the beginning. As the time the copy job takes is not really improved by this method the slowdown in the end once the cache is filled is inevitable.
You can easily check if your script is at fault by just manually starting the same copy but as you use the windows explorer file copy anyway I doubt that anything in your script is at fault here.
Having trouble with WSH and Windows Compression.
My goal is to be able to zip up files (not folders, but individual files from various locations, which I have stored in an array) using the built-in Windows Compression. I am using VB6.
Here is my routine (vb6 code):
Dim objShell
Dim objFolder
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.namespace(savePath & "\export.zip")
' --
' loop through array holding files to zip
For i = 0 To filePointer
objFolder.CopyHere (filesToZip(i))
Next
' --
Set objShell = Nothing
Set objFolder = Nothing
It works, but issues arise when there are more than a few files. I start getting errors from Windows (presumably, its calling the compression too fast, and the zip file is locked). I cant seem to figure out how to WAIT until the COPYHERE function completes before calling the next one to avoid issues.
Does anyone have any experience with this?
Thanks -
You should be able to achieve that sort of synchronization by checking the file count in your target ZIP folder before proceeding to the next loop iteration (as suggested here and here):
For i = 0 To filePointer
objFolder.CopyHere filesToZip(i)
Do Until objFolder.Items.Count = i+1
WScript.Sleep 100
Loop
Next