I want to run following script as scheduled task on Windows 7 in background. Now, script displays cmd window and, can I run script without visible cmd window?
Option Explicit
Dim WshShell, oExec
Dim RegexParse
Dim hasError : hasError = 0
Set WshShell = WScript.CreateObject("WScript.Shell")
Set RegexParse = New RegExp
Set oExec = WshShell.Exec("%comspec% /c echo list volume | diskpart.exe")
RegexParse.Pattern = "\s\s(Volume\s\d)\s+([A-Z])\s+(.*)\s\s(NTFS|FAT)\s+(Mirror|RAID-5)\s+(\d+)\s+(..)\s\s([A-Za-z]*\s?[A-Za-z]*)(\s\s)*.*"
While Not oExec.StdOut.AtEndOfStream
Dim regexMatches
Dim Volume, Drive, Description, Redundancy, RaidStatus
Dim CurrentLine : CurrentLine = oExec.StdOut.ReadLine
Set regexMatches = RegexParse.Execute(CurrentLine)
If (regexMatches.Count > 0) Then
Dim match
Set match = regexMatches(0)
If match.SubMatches.Count >= 8 Then
Volume = match.SubMatches(0)
Drive = match.SubMatches(1)
Description = Trim(match.SubMatches(2))
Redundancy = match.SubMatches(4)
RaidStatus = Trim(match.SubMatches(7))
End If
If RaidStatus <> "Healthy" Then
hasError = 1
'WScript.StdOut.Write "WARNING "
MsgBox "Status of " & Redundancy & " " & Drive & ": (" & Description & ") is """ & RaidStatus & """", 16, "RAID error"
End If
End If
Wend
WScript.Quit(hasError)
Thanks a lot
Option 1 - If the task is running under your user credentials (if not, msgbox will not be visible)
There are two possible sources for the cmd window.
a) The script itself. If the task is executing cscript, the console window will be visible, avoid it calling wscript instead
b) The Shell.exec call. The only way to hide this window is to start the calling script hidden. On start of your script test for the presence of certain argument. If not present, make the script call itself with the argument, using Run method of the WshShell object, and indicating to run the script with hidden window. Second instance of the script will start with the special parameter, so it will run, but this time windows will be hidden.
Option 2 - Running the task under system credentials.
In this case, no window will be visible. All will be running in a separate session. BUT msgbox will not be seen. Change MsgBox call with a call to msg.exe and send a message to current console user.
Related
I have been trying to create a really simple script to maintain visibility on an IE page but am currently unable to force the visibility or foreground position of an existing IE window.
I am able to successfully activate the window using WshShell.AppActivate() but it does not make the page foreground to a user. A sample from my code is below.
Basically the code loops until the user ends the notepad window. my confusion is specifically with why IE is not visible no matter what commands I send
Dim pressX
Dim FindProc
pressX = 1
' Create WScript Shell Object to access filesystem.
Set WshShell = WScript.CreateObject("WScript.Shell")
'WshShell.Run "NoScreenSaver.txt", 2, 0
' Define Which process to seek for to terminate script
strComputer = "."
FindProc = "NoScreenSaver"
Dim objApp : Set objApp = CreateObject("Shell.Application")
Dim IE : Set IE = Nothing
Dim objWindow
' Loop start
Do
' Wait for 5 minutes
WScript.Sleep 3000 '000
For Each objWindow In objApp.Windows
If (InStr(objWindow.Name, "Internet Explorer")) Then
Set IE = objWindow
Exit For
End If
Next
' check if specific notepad closed
If WshShell.AppActivate("NoScreenSaver.txt") = True Then
'WshShell.AppActivate("iexplore.exe")
'wscript.echo FindProc & " is running"
Else
wscript.echo FindProc & " is not running" & vbCrLf & "Script will now end"
pressX = 0
End If
IE.visible = True
wshshell.appactivate ie.name
IE.navigate "google.ca"
' Send dummy key
WshShell.SendKeys "{F13}"
' repeat
Loop While pressX
I never wanted to use AppActivate to check for the specific notepad window either since it would take foreground. There is some information regarding using a COM wrapper but the COM wrapper approach is not possible within my constraints.
I have a VBScript to back up several registry keys into a single file:
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
arrRegPaths = Array( _
"HKEY_CURRENT_USER\RegKey1\", _
"HKEY_CURRENT_USER\RegKey2\", _
"HKEY_CURRENT_USER\RegKey3\" _
)
Const intForReading = 1
Const intUnicode = -1
strFileName = objShell.ExpandEnvironmentStrings("%UserProfile%") & "\FolderName\FileName.reg"
Set objRegFile = objFSO.CreateTextFile(strFileName, True, True)
objRegFile.WriteLine "Windows Registry Editor Version 5.00"
For Each strRegPath In arrRegPaths
strCommand = "cmd /c REG EXPORT " & strRegPath & " " & Replace(strRegPath, "\", "_") & ".reg"
objShell.Run strCommand, 0, True
If objFSO.FileExists(Replace(strRegPath, "\", "_") & ".reg") = True Then
Set objInputFile = objFSO.OpenTextFile(Replace(strRegPath, "\", "_") & ".reg", intForReading, False, intUnicode)
If Not objInputFile.AtEndOfStream Then
objInputFile.SkipLine
objRegFile.Write objInputFile.ReadAll
End If
objInputFile.Close
Set objInputFile = Nothing
objFSO.DeleteFile Replace(strRegPath, "\", "_") & ".reg", True
End If
Next
objRegFile.Close
Set objRegFile = Nothing
I can run it directly from Explorer (Win10), directly from CMD, or with WScript/CScript, and it works perfectly. Takes about 2 seconds to complete, and the output file has everything it's supposed to have.
But when I try to run it as a scheduled task, it never finishes running. I've let it sit for several minutes, before manually killing it. When I look at the output file after this, all it has is the first line, Windows Registry Editor Version 5.00. So I know the script is finding the target file OK, and it's running the first WriteLine. But after that, it hangs or something.
How can I make it work as a scheduled task?
Haven't tried your code, but you send a commandline command from within your script. That seems counterintuitive to me. You are probably better off by tapping into the registry directly from your script. You can find examples of how to do that here: https://learn.microsoft.com/en-us/windows/desktop/WmiSdk/wmi-tasks--registry
Got it figured out, and it actually had little to do with the code. I'll post the answer in case anyone else runs across something similar. It turns out that the problem was in the scheduled task itself—I needed to put a folder in the "Start in" box (when specifying the action to be scheduled). I assume this is because the script outputs to temp files along the way, so it needed a place to put those. Anyway, once I filled in that blank, it began running successfully.
When creating multiple environment variables in sequence using VBS, the earlier variables are never getting expanded when referenced in the later variables.
Set wshUserEnv = objShell.Environment( "USER" )
wshUserEnv("A") = "a"
wshUserEnv("b") = "%A%\b"
Then,
objShell.ExpandEnvironmentStrings(GetEnvVariable("b"))
does not give the value of a\b, but, instead stays as %A%\b
Also, listing the values from command line prints the same value. But, once the variable is edited (minor edit like adding a semicolon) from System Properties dialog, the variable gets expanded.
GetEnvVariable is a helper function:
Function GetEnvVariable (EnvVariable)
Dim wshUserEnv
Set wshUserEnv = objShell.Environment( "USER" )
GetEnvVariable=wshUserEnv(EnvVariable)
End Function
Regarding .ExpandEnvironmentStrings() behavior:
Run the first script below:
Set objShell = CreateObject("WScript.Shell")
' set values to variables
objShell.Environment("user")("user___var") = "user___value"
objShell.Environment("process")("process___var") = "process___value"
objShell.Environment("system")("system___var") = "system___value"
objShell.Environment("volatile")("volatile___var") = "volatile___value"
s = "check accessibility within running script process" & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%user___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%process___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%system___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%volatile___var%") & vbCrLf
WScript.Echo(s)
objShell.Run "cmd.exe /k echo check accessibility within child process & echo %user___var% & echo %process___var% & echo %system___var% & echo %volatile___var%"
The output will be the same for both WScript.Echo and cmd.exe /k echo:
%user___var%
process___value
%system___var%
%volatile___var%
After that run the second script:
Set objShell = CreateObject("WScript.Shell")
s = "check accessibility via another script process" & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%user___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%process___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%system___var%") & vbCrLf
s = s & objShell.ExpandEnvironmentStrings("%volatile___var%") & vbCrLf
WScript.Echo(s)
objShell.Run "cmd.exe /k echo check accessibility via another script process & echo %user___var% & echo %process___var% & echo %system___var% & echo %volatile___var%"
The output will be:
user___value
%process___var%
system___value
volatile___value
I've checked behavior on Win7 x64 and VirtualBox WinXP. As you can see, process environment is only accessible for .ExpandEnvironmentStrings() within running process or via child process, that first script shows. Other environments are not accessible for .ExpandEnvironmentStrings() until running script (in which variables were set) finishes. When you run second script, you become able to read all environments variables via .ExpandEnvironmentStrings(), except process.
I hope this explanation will help to get your code to work.
The code you show objShell.ExpandEnvironmentStrings(GetEnvVariable("b")) gives you %A%\b because GetEnvVariable("b") returns %A%\b (.Environment() method implemented in the function has access to user environment, and all others environments, but it doesn't process contained %A% as variable statement, as .ExpandEnvironmentStrings() does), and then .ExpandEnvironmentStrings("%A%\b") returns the value without any changes (the method has no access to A variable in user environment till script termination).
I have created a VB script which creates a shortcut to execute my test_application.exe. I want my application to run without a console. I am using following script to create the shortcut
Create_ShortCut "C:\Users\Me\bin\MyApplication.exe", "Desktop", "My-Test", "C:\Users\Me\bin" , 0, 1
Private Sub Create_ShortCut(TargetPath, ShortCutPath, ShortCutname, WorkPath, Window_Style, IconNum)
Dim VbsObj
Set VbsObj = CreateObject("WScript.Shell")
Dim MyShortcut
ShortCutPath = VbsObj.SpecialFolders(ShortCutPath)
Set MyShortcut = VbsObj.CreateShortcut(ShortCutPath & "\" & ShortCutname & ".lnk")
MyShortcut.TargetPath = TargetPath
MyShortcut.Arguments = "127.0.0.1 5000 -exec=C:\Users\Another\other_application.exe"
MyShortcut.WorkingDirectory = WorkPath
MyShortcut.WindowStyle = Hidden
MyShortcut.WindowStyle = 0
MyShortcut.IconLocation = TargetPath & "," & IconNum
MyShortcut.Save
End Sub
I would like to start my application in invisible window and the other application to start in a normal window. When I create a shortcut like this I am not able to run my application in invisible mode. Am I doing anything wrong ?
Don't target the console subsystem. If you do, expect to see a console. Instead target the GUI subsystem.
I'm using code below to execute my commands in cmd. Which is actually made for running an exe on my server.
Private Sub Command1_Click()
Dim FN As Integer
FN = FreeFile
'DOS COMMANDS
ServerName = "\\mydbserv"
ExePath = """d:\myfolder\my.exe"""
UserName = "myserver\myuser"
Password = "mypass"
MyCommand = "psexec " & ServerName & " -u " & UserName & " -p " & Password & " -i " & ExePath
'Open Bat file
Open "C:\Mybatc.bat" For Output As #FN
Print #FN, "cd c:\Users\myuser"
Print #FN, MyCommand
Print #FN, "Exit"
Close #FN
'Activate
result = Shell("C:\Mybatc.bat", vbHide)
End
End Sub
everything was fine until i seen that cmd is not getting closed when process is done.
and the worse is the exe i was trying to run remotely also not stops. When i check the cpu usage it always shows "00" doesnt even starts.. It shows like working for ever but never works actually.
So my question is :
Why i cant run this exe file remotely? (or why it just shows like running)
How can i remotely run and close when finished this exe file on server?
How can i close the window and process when finished on my pc as well?
How about this?
install Windbg on the server.
config the windbg auto attach to your exe, when your exe is ready to running.
http://ask.brothersoft.com/image-file-execution-options-debugger-83827.html
running your script
after your exe is started, the windbg will attach to it.
input 'g' in the windbg command, let your exe to running.
wait until you think it should finished
ctrl-break to let the process hang on
input '~*kb' to windbg command, to see what's going on in every thread,
to find out why they are waiting, and what they are waiting for?
PSExec will only initiate the start of the process in a computer (most of the time remote), after that it has no control on the exe that is being executed. Kindly try to run it as a process (within a ProcessInfo as in C#)(with shell execute false). Also something like the following can be used to confirm the state of the process in remote PC:
Option Explicit
Private Sub Form_Load()
Dim strComputer As String
Dim sReturn As String
Dim strNameOfUser As Variant
Dim colProcesses As Object
Dim objProcess As Object
strComputer = "." '"." local or "\\ComputerName"
Set colProcesses = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery("Select * from Win32_Process")
For Each objProcess In colProcesses
sReturn = objProcess.GetOwner(strNameOfUser)
If sReturn <> 0 Then
MsgBox "Could not get owner info for process " & objProcess.Name & vbNewLine & "Error = " & sReturn
Else
MsgBox "Process " & objProcess.Name & " is owned by " & "\" & strNameOfUser & "."
End If
Next
End Sub
link : http://www.vbforums.com/showthread.php?355203-RESOLVED-How-to-get-process-information
hope it helps