How to make vbs message box "always on top" - vbscript

I came across one or two posts on this topic, such as:
Create vbscript messagebox that stays on top and blocks other windows
but this doesn't seem to work with an 'if.. else' argument. Whenever I try to add anything of the like to the second line of my script, I get WSH VBScript compilation error messages.
This is the script, and I am trying to make it remain visible above all other windows which open on the screen after it has appeared. Would appreciate help. Thanks,
Martin
intAnswer = _
Msgbox(" Do you want to run FS Earth?", _
vbYesNo, " ")
If intAnswer = vbYes Then
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Run("""D:\FS9\FS_Earth\fs_earth_link.exe""")
Set objShell = Nothing
Else
End If

I spent a good 5 minutes reading your question over and over again..I feel a bit silly - it finally dawned on me what you were asking!
Currently, you can't add anything on line two, because your first three lines of code are actually a single instruction spanned across multiple lines (by use of the underscore _ character).
If you rewrote your code as below, you could certainly add whatever you like between line 1 and 2 :)
intAnswer = Msgbox("Do you want to run FS Earth?", vbYesNo + vbSystemModal, " ")
If intAnswer = vbYes Then
Dim objShell
Set objShell = WScript.CreateObject( "WScript.Shell" )
objShell.Run("""D:\FS9\FS_Earth\fs_earth_link.exe""")
Set objShell = Nothing
Else
End If

you can't really control the layering because those other windows are separate processes and the msgbox belongs to the process that launched the vbs.

Related

Multi line vbs auto typer from .txt file [duplicate]

This question already has answers here:
Single Line Input VBS Autotyper
(2 answers)
Closed 2 years ago.
So i have been working on a troll terminal and now i want to type out the entire bee movie script or whatever i put in a text file.
What i need help with is taking the text(with enters and spaces) and fully typing it out.
Another way to say it is i want to take a text file and copy it threw typing it out.
I couldnt find any decent code to do this wich is why i'm asking here.
Also if possible make it type anything that you put in the text file.
(I have no clue why it doesnt let me post this)
Idea: I might know another way around but i dont know how to get it done.
Maby there is a way to infinetly generate variables for each line and type them out like that.
Other idea: I might be able to make a tool to let me quickly hard code it.
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("C:\yourfirstfile", 1)
content = file.ReadAll
Const fsoForAppend = 8
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
'Open the text file
Dim objTextStream
Set objTextStream = objFSO.OpenTextFile("C:\yoursecondfile", fsoForAppend)
'Display the contents of the text file
objTextStream.WriteLine content
'Close the file and clean up
objTextStream.Close
Set objTextStream = Nothing
Set objFSO = Nothing
Set wshShell = CreateObject("Wscript.Shell")
wshShell.run "C:\yoursecondfile"
Tell me if it works
Yes i m self anwsering.
This script works but it double taps enter i will update it if i figure out how to stop that from happening.
Set wsh=WScript.CreateObject("WScript.Shell")
sub custom_text_typer_confirm
Set objFileToRead =WScript.CreateObject("Scripting.FileSystemObject").OpenTextFile("Custom_Text_Typer.txt",1)
strFileText = objFileToRead.ReadAll()
objFileToRead.Close
custom_typer_wait = inputbox("How long should the program wait untill it will start typing?", "Eclips-Terminal Custom Text Typer")
custom_typer_wait1=custom_typer_wait * 1000
Wscript.sleep custom_typer_wait1
wsh.sendkeys (strFileText & "{enter}")
Wscript.sleep 1000
call home
end sub

How to hide Windows Script Host window?

I started using today a program named "oblytile", which gives you the ability to add custom tiles to Metro UI in Windows 8/8.1. The program works fine, but I have one big issue when I open created tile to folder, program, file etc. for a short time a small black window (like CMD) pops up, like here:
and after the window disappears the program I wanted opens. I have watched some YouTube videos and other people didn't have something like this. I checked folder in which one program stores data about tiles and I found out that evry time I click on custom tile in Metro UI a VBScript is started.
Sample tile VBScript:
On Error Resume Next
Set objShell = CreateObject("Wscript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strApp = "C:\Users\bluea_000\OneDrive"
arrPath = Split(strApp, "\")
For i = 0 to Ubound(arrPath) - 1
strAppPath = strAppPath & arrPath(i) & "\"
Next
objShell.CurrentDirectory = strAppPath
objShell.Run """C:\Users\bluea_000\OneDrive""" & ""
If Err.Number <> 0 Then
If InStr(1, strApp, "/") > 0 then
Else
If InStr(1, strApp, "www.") > 0 then
Else
If InStr(1, strApp, "shell:") > 0 then
Else
If objFSO.folderExists(strApp) Then
Else
If objFSO.FileExists(strApp) Then
Else
MsgBox strApp & " not found", 16, "OblyTile"
End If
End If
End If
End If
End If
Err.Clear
End If
Can anyone tell me how to hide this black window or fix it?
I asked on forum where the program was published, but probably the project has been abandoned and noone will answer me.
There are two interpreters for vbs files. Wscript and cscript.
Cscript is the command-line based scripting host and, thus, opens the black console window, wscript is the windows based scripting host and doesn't open a command-line window.
Use wscript for executing your script and no black window will pop up.
See https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/wsh_runfromwindowsbasedhost.mspx

Can I list apps that don't have registry entries?

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

VBscript Unable to Run Shell Command

I have set up the following Sub to run shell commands quickly and easily.
This script works for the login scripts at my company without fail.
I am currently developing a script to add a large batch of users to our domain.
When I used this Sub in my new script I receive an error saying that the file cannot be found.
I have tried using the fix in this stackoverflow post, but I recieve the same error even with this code.
VBScript WScript.Shell Run() - The system cannot find the file specified
The part I find puzzling is that this sub works just fine when run from the netlogon folder of our domain controller.
What am I doing wrong?
Thanks,
Sub runcommand(strCommand)
Dim objWshShell, intRC
set objWshShell = WScript.CreateObject("WScript.Shell")
intRC = objWshShell.Run(strCommand, 0, TRUE)
call reportError(intRC,strCommand)
set objWshShell = nothing
end Sub
function reportError(intRC, command)
if intRC <> 0 then
WScript.Echo "Error Code: " & intRC
WScript.Echo "Command: " & command
end if
end function
The previous values for strCommand had no spaces and were very straightforward. Your new script is passing more complex variables to your Sub so you need additional conditional handling, as Alex K. pointed out in his Collusion (i.e., "Comment/Solution") above. Alex K.'s sample above is perfect, so, being a Point Pimp tonight, will post it as the solution:
objWshShell.Run("cmd /k echo Hello World", 1, TRUE)

how to check vbs script in windows is running or not?

I have created a VBS script in Windows. I will run this script to get size of a file.
I made this to run for ever. (even this is my requirement).
How should I know if it is running or stopped?
------ Exact Script starts here -----
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSO_check=CreateObject("Scripting.FileSystemObject")
do while infiniteLoop=0
----- This code is lasting for ever ----
Loop
Am i clear in my ques?
How about using the commandline property? I think this need Windows XP and up.
For example:
Set objSWbemServices = GetObject ("WinMgmts:Root\Cimv2")
Set colProcess = objSWbemServices.ExecQuery _
("Select * From Win32_Process where name = 'wscript.exe'")
For Each objProcess In colProcess
WScript.Echo objProcess.Name, _
objProcess.ProcessId, _
objProcess.CommandLine
Next
I made a script and at the beginning i wanted to avoid having multiple / duplicate instances of the same process running. This is my code to quit the newer instance in case it gets launched when already running.
Note: This does note prevent multiple wscripts files from running - just prevents the same particular file from having simultaneous instances.
To adapt to suit the original question... just use the block which checks current running processes, if the any of the wscript file names equal the script file you're looking for, then it's running.
function duplicate_check
'if two scripts get here at the same time - stagger when the generate _
'the list of running processes _
'ie - give 1 of them time to close
'else they can both quit leaving no more scripts running
call random_script_sleep(2500,500)
dim myfilename
myfilename = Wscript.ScriptName
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from win32_process")
'fill arrary w/ all running script names
i = 0
For Each objProcess in colProcesses
If objProcess.Name = "wscript.exe" Then
strScriptName = Trim(Right(objProcess.CommandLine,Len(objProcess.CommandLine) - InstrRev(objProcess.CommandLine,"\")))
strScriptName = Left(strScriptName, Len(strScriptName) - 1)
a(i)= strScriptName '
i=i+1
end if
Next
'kill script if already running w/ same name
if i > 1 then 'if > 1 wscript instance
for s = 0 to i
if a(s) = myfilename then
wscript.quit
end if
next
end if
'sometimes duplicate check fails, if so, write to error log
If Err.Number = 1 Then
error_notes = " #duplicate check, firstdupcheck(0/1):" & firstdupcheck
call error_log
error_notes = "error undefined"
end if
' if debugmsg = 1 then CreateObject("WScript.Shell").Popup _
' "found this many scripts: " & i & vbCrlf & _
' "<>" & i & vbCrlf & _
' ", 1, "debug popup"
end function
#nimizen answer is not correct. If you have another wscript running, it will return that your script is already running.
#h pic answer is correct, but I get an error with the "a" array in my windows. So I changed it a little and cleaned to work.
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from win32_process where name = 'wscript.exe'")
i = 0
For Each objProcess in colProcesses
if not (IsNull(objProcess.CommandLine )) then
strScriptName = Trim(Right(objProcess.CommandLine,Len(objProcess.CommandLine) - InstrRev(objProcess.CommandLine,"\")))
strScriptName = Left(strScriptName, Len(strScriptName) - 1)
if strScriptName = Wscript.ScriptName then
i=i+1
end if
if i > 1 then 'if > 1 wscript instance
'Wscript.Echo "Duplicate :"&strScriptName&" ."
Wscript.Quit
end if
end if
Next
'Wscript.Echo "Pause 2 have 2 scripts running ."
Hmm, well first if its an infinite loop script, then you're probably using it to periodically check a folder to do some work. This sounds bad but is usually less resource intense than hooking into WMI for notifications. If its up and running, its running. The real problem is discriminating it from all the other WScript and CScripts scripts you may have running.
MS Sysinternals Process Explorer http://technet.microsoft.com/en-us/sysinternals/bb896653 is good at telling you information about your running processes. Mostly I would use it to tell by unique command line arguments which script process is hosting which script.
There is no easy way to exactly find your script's process Id from within a script. It is one of the few pieces of runtime information not exposed in the script environment's object model. Since you are already using the File System Object perhaps you could have it look for a dummy file name to use as the indicator that it is running. If the script couldn't create or open the file then you could assume that another instance of the script is already running.
Or have another unique named dummy file that you can easily create and your script automatically deletes during its processing run. That way you simply create an empty file of that name as a test and if it doesn't disappear in a few seconds you know no instances of your script are running.
Also I was thinking that you could launch your script from another script using Exec() which returns the ProcessID of the launched script and then release your reference to it, storing the ProcessID wherever you need it for later use.
Set oExec = WshShell.Exec( "infinite.vbs" )
MyProcessID = oExec.ProcessID ' procID of shell'd program.
set oExec = Nothing
and do something with MyProcessID
Then I noticed this posting
Find my own process ID in VBScript
Which uses Exec() to run an HTA script, get its ProcessID and look that up in WMI, then use the result set from WMI to locate the Parent process' ProcessID which should be the script making the Exec() and WMI calls. The problem with it is the HTA may terminate before WMI gets a chance to find it.
Dim iMyPID : iMyPID = GetObject("winmgmts:root\cimv2").Get("Win32_Process.Handle='" & CreateObject("WScript.Shell").Exec("mshta.exe").ProcessID & "'").ParentProcessId
Mostly I get the feeling that this is all overkill for whatever reason you think you need to know if the script is running. Instead focus on what action "knowing if the process is running or not" causes you to take. Since that hasn't been explained we really can't offer you an alternative strategy to get you there, but I'm sure a more simple solution is available. TheFolderSpy http://venussoftcorporation.blogspot.com/2010/05/thefolderspy.html for example would be one alternative way to run your program without an infinite loop.
Don't forget to use a sleep command in your loop to let other programs get work done. It makes a great difference in resource use. Also you only need one FSO instance, make it global to all your code by creating it early on in your script before any subroutines.
Since you are looking at the size of a file, you are probably checking it for changes. I've found that a loop with a small WScript.Sleep 200 delay in it is good to detect if a file is done being altered. That way you can process the file instead of having to skip it until the next main loop pass which should be set to 10 seconds or more.

Resources