vbscript-terminating process instance - process

I'm writing a script that runs an external program, and after a while terminates it, the relevant code section looks like this:
Set objshell=createObject("Wscript.Shell")
objShell.run ""app.exe""
objShell.run ""app.exe""
WScript.Sleep(5000)
strWmiq = "select * from Win32_Process where name='app.exe'"
Set objQResult = objWmi.Execquery(strWmiq)
For Each objProcess In objQResult
intRet = objProcess.Terminate(1)
Next
What I want to do is to close each of the instances of app.exe after different sleep times, any ideas how to do that?

Use WScript.Shell's .Exec method to get a WshScriptExec objects for each session/run/instance of app.exe and .Terminate them at your leisure (and risk). See Terminate Method (WshScriptExec)

Related

Can you determine if FFmpeg executed correctly based on the return?

I have written a script to mass-tag a large audio library. The tag info is stored in an Access database. I wrote a vba sub that invokes an FFmpeg command line.
newCmdStr = ffmpeg -i myFile.mp3 tag-info output.mp3
Shell ("cmd.exe /k " & newCmdStr)
Is there a way to determine if it runs correctly?
I tried printing the return
MsgBox(Shell(newCmdStr)),
but it seems to return a random number, I can't tell what indicates if the command worked.
The most likely error would be a file not found error, but there could be some other things.
If it ran, I would log the filepath of the new file, if it failed I would note that.
Shell invokes a command asynchronously, and can never get a return value. It returns the Process ID.
Furthermore, it would return the program ID of the program you're trying to run, which, in this case, is cmd.exe since that's first in your string.
Use WScript.Shell instead, which has .Run which can invoke commands synchronously, or .Exec which invokes asynchronously but allows getting return values.
Dim WshShell, oExec
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("ffmpeg -i myFile.mp3 tag-info output.mp3")
Do While oExec.Status = 0
DoEvents
'You probably want to sleep here to prevent high CPU usage
'See https://stackoverflow.com/a/469358/7296893
Loop
Debug.Print oExec.ExitCode

wshshell.popup not being displayed to other user when using task scheduler

I've got a tricky thing to do here.
I'm using task scheduler to auto-reboot all the computer during the weekend by calling a simple .bat file containing a shutdown command.
I wanted to give the user the possiblilty to cancel that reboot by displaying them a popup saying "Computer is about to restart, do you wish to continue ? Ok or Cancel". I have done that with VB using the popupbox method, it works perfectly.
Here is the problem i'm facing: The task is running under the System account and unless the task is set to run with the current logged on user, the popup box won't appear. I could change the account set in the task but I've got hundreds of users so impossible.
I've done some kind of a workaround, calling the VBS from Psexec... Works, but it's not perfect.
Here is my Psexec command that calls the VB:
Psexec -accepteula -s -i cmd /c C:\Windows\System32\Weekly_Reboot.vbs
Here is my VB:
Dim WshShell, BtnCode
Set WshShell = WScript.CreateObject("WScript.Shell")
BtnCode = WshShell.Popup("Computer is about to restart, do you wish to continue?", 30, "/!\ Weekly Restart /!\", 4 + 32)
Select Case BtnCode
case 6
Dim objShell
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "c:\Windows\System32\Weekly_Reboot.bat"
case 7
WScript.Echo "No prob - the computer won't restart"
case -1
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "c:\Windows\System32\Weekly_Reboot.bat"
End Select
And here is the actual reboot command:
Shutdown /f /r /c "This is the weekly reboot"
Any idea would be really awesome ! I really tried googling it, but no luck.
Here is the problem i'm facing: The task is running under the System account and unless the task is set to run with the current logged on user, the popup box won't appear. I could change the account set in the task but I've got hundreds of users so impossible.
Change the task to run under the group called Users. It will make the task run for any logged in user.
I'm not certain if this is needed: but you might want to run it using the highest privileges.

WScript.Shell.run on multi thread

I would like to know if there is a way to run a shell window on another thread than excel ?
The idea is to not freeze excel when I launch a shell.
for instance :
Dim objShell
Set objShell = WScript.CreateObject ("WScript.shell")
objShell.run "cmd /K CD C:\ & Dir"
Set objShell = Nothing
Thanks for your help
I would agree and disagree with Praktik. I agree because you cannot create a real multi-threaded application in Excel. I disagree because you could use kind of trick to execute another script.
Let's assume you have a vbs script called "Script.vbs". Then you could code sth like this taskId = Shell("wscript Script.vbs parms"). The script would run independently from your VBA program. But may that's not what you want.
The answer would be NO, you cannot create multi-threaded application in Excel.
However you can use Application.ScreenUpdating = False to lock the current Excel Workbook.
Make sure you enable it back at the end of the code like so Application.ScreenUpdating = True
Hope that helps!

Check if process is done in VB.Net

We have this process and we want to know if the process is done? How we'll be able to check if it is done?
Here is the code:
Process.Start(filePath & ".bat", filePath.Substring(0, filePath.LastIndexOf("\")))
thanks
There are several properties/methods you can use after you have saved the return value of Process.Start to a variable:
If you want to wait until the Process has exited, use the WaitForExit method.
If you want to check whether the Process is still running, use the HasExited property.
If you need the exit code after the Process has ended, use the ExitCode property.
For an overview of the Process class and its capabilities, see this link.
Sample:
Dim p As Process = Process.Start(filePath & ".bat", filePath.Substring(0, filePath.LastIndexOf("\")))
p.WaitForExit()

VB.net - Running a java application using Shell() and set its appdata folder. multiple commands?

Alright guys I have a copy of minecraft wich is a java program launched by Minecraft.exe.
Inside the same folder is my program (lets call it launcher.exe) wich I am programming in VB.net and a Folder called LocalAppData.
If I place a shortcut in the same folder as Minecraft.exe, clear the "start in" field and put this in the target field:
C:\Windows\System32\cmd.exe /c start cd LocalAppData&& set APPDATA=%cd%\LocalAppData&& javaw -Xms4096M -Xmx4096M -cp LocalAppData\Minecraft.exe net.minecraft.LauncherFrame
then minecraft launches with my custom memory allocation from inside the LocalAppData folder. Two command windows appear as well. One closes when minecraft does, but the other does not and needs to be closed by the user
My Question is: How do I acheive the same result in VB.net instead of with a windows shortcut and is there a way to either stop the command windows appearing or setting them both to close automatically?
My goal is to launch minecraft from a subfolder, so local filepaths would be far preferrable to global filepaths, but figuring out the location of the application at runtime and working from a subfolder would be ok as well.
I thought I would be able to use the same code inside a Shell() command to produce the same effect, but it appears not.
Ideally I want to create a program that runs minecraft with:
Custom memory allocation
Local filepaths so that it can be run portably
The appdata folder changed to the subfolder so that it can be run portably
Those command windows either gone or minimised and then close automatically when minecraft is closed by the user.
I know this is a big ask, but I'm 6 months into a programming course and I'll admit that I'm not the best programmer out there.
Once I know how to do this I can create the rest of the program that manages multiple installations in seperate subfolders and lets you choose wich one to launch, but I just need help with the actual launching of the java application itself.
Note:
I should clarify that Minecraft.exe is not something that I have made and that I don't program java. I'm just looking for a solution in VB.Net.
Thank you for reading all this and sorry for the long post.
Edit
Thank you for the help. This is what I have so far, but it produces an error "Error: Could not create the JavaVirtualMachine. Error: A fatal exception has occurred. Program will exit"
'Declare Processes
Dim appDataStartInfo As ProcessStartInfo = New ProcessStartInfo()
Dim javaStartInfo As ProcessStartInfo = New ProcessStartInfo()
Dim appPath As String = Application.StartupPath()
'Launch appdata relocation process
appDataStartInfo.FileName = "cmd.exe"
appDataStartInfo.Arguments = "/c start cd " & appPath & "&& set APPDATA=" & appPath & "\LocalAppData"
appDataStartInfo.UseShellExecute = True
Process.Start(appDataStartInfo)
'Launch Minecraft
javaStartInfo.FileName = "javaw.exe"
javaStartInfo.Arguments = "-Xms4096M -Xmx4096M -cp " & appPath & "\LocalAppData\.minecraft\bin\Minecraft.jar net.minecraft.LauncherFrame"
javaStartInfo.UseShellExecute = True
Process.Start(javaStartInfo)
Does anyone see where I've gone wrong?
The Process class (http://msdn.microsoft.com/en-us/library/system.diagnostics.process.aspx )allows you to launch a process. You set it up with a ProcessStartInfo instance (http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo(v=vs.80).aspx ).
I don't have the time to give you all the details, but this pseudo-code should get you started :
Dim startInfo As ProcessStartInfo = new ProcessStartInfo()
startInfo.FileName = "javaw.exe" 'That's the name of your executable
startInfo.Arguments = "your argument line"
startInfo.UseShellExecute = true 'Needed to open a command window
Process.Start(startInfo)