How to hide Windows Script Host window? - windows

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

Related

Closing open processes (except excluded) via VBScript

Currently I use the below portion of VBScript to close running processes, and it works great. But the management issue is that if there's an unknown process, the script isn't going to close it. So I'd like to change this to where all running processes are terminated, unless they're specifically excluded (as there are a few processes that I do not want terminated).
Dim WshShell, objShell
Set WshShell = CreateObject("WScript.Shell")
AppList = "iexplore.exe,notepad.exe,wordpad.exe"
'Closing all open applications that are specified in AppList
For Each app In Split(appList, ",")
Set objProcs=GetObject("winmgmts:\\.\root\cimv2").ExecQuery("select * from Win32_Process where Name= '" & app & "'")
For Each process In objProcs
On Error Resume Next
process.Terminate
On Error Goto 0
Next
Next
I've looked, but can't seem to find anything. And I'm ok using a PowerShell command (as all PC's will be Win10), as long as the PS command can be run completely inside of this VBS, without having to maintain a separate PS file.
So something like this would acceptable:
objShell.Run("powershell.exe -switch1 -switch2")
But not this:
objShell.Run("powershell.exe c:\scripts\test.ps1")
The idea of killing all processes except those in an exclude list sounds pretty risky to me. Can you really be sure your exclusion list is complete? New processes (that you may want/need) can be added at any time. This might be okay on a special purpose machine, but I wouldn't use this approach on my general purpose PC. Anyhow, here's the script. Use at your own risk.
Note: With KillEnabled set to False, the script just displays the Exe names that would be killed. Change that value to True to go live. Run using CScript (e.g. cscript killx.vbs).
KillEnabled = False
UserExesOnly = True
Exclude = "applicationframehost,backgroundtaskhost,chsime,cmd,conhost,cscript,ctfmon,dllhost,explorer,mshta,runtimebroker,settingsynchost,searchapp,shellexperiencehost,sihost,smartscreen,startmenuexperiencehost,svchost,systemsettings,textinputhost,useroobebroker,video.ui,wscript"
Exclude = LCase(Exclude)
Set oWMI = GetObject("winmgmts:\\.\root\cimv2")
Set oWSH = WScript.CreateObject("WScript.Shell")
If UserExesOnly Then X = " Where SessionID = 1"
Set oProcesses = oWMI.ExecQuery("SELECT * FROM Win32_Process" & X)
For Each oProcess In oProcesses
Kill = False
ExeName = LCase(oProcess.Name)
If InStr(ExeName,".exe") Then
Kill = True
For Each Exe In Split(Exclude,",")
If InStr(ExeName,Exe & ".exe") Then Kill = False
Next
If Kill Then
If KillEnabled Then
oProcess.Terminate
Else
WScript.Echo ExeName
End If
End If
End If
Next

.VBS called by .BAT to create .zip - run silently (without interface)?

I have a .bat file which I use to back up files, which calls a .vbs and passes it two parameters, as follows:
...
ZipCMD.vbs "C:\Source" "C:\Destination\Data.zip"
...
ZipCMD.vbs contains the following code (Credit to garbb):
Set objArgs = WScript.Arguments
Set FS = CreateObject("Scripting.FileSystemObject")
InputFolder = FS.GetAbsolutePathName(objArgs(0))
ZipFile = FS.GetAbsolutePathName(objArgs(1))
CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" & Chr(5) & Chr(6) & String(18, vbNullChar)
Set objShell = CreateObject("Shell.Application")
Set source = objShell.NameSpace(InputFolder).Items
numfolderitems = objShell.NameSpace(InputFolder).Items.count
objShell.NameSpace(ZipFile).CopyHere(source)
' wait until number of items in zip file is the same as in the folder we are zipping up
' also sometimes gets errors when getting folder object for zip file, probably because it is in use? so ignore these
On Error Resume Next
Do while True
numitemsinzip = objShell.NameSpace(ZipFile).Items.count
If Err.Number = 0 and numitemsinzip = numfolderitems Then
Exit Do
ElseIf Err.Number <> 0 then
Err.Clear
End If
wScript.Sleep 10
Loop
On Error Goto 0
When the zipping is occurring, the usual windows 'Compressing files' interface appears, and shows the progress bar ticking along for a few minutes, before closing and disappearing.
Question: Can vbs run a compression silently (i.e. without interface)? -- I've read this article, which shows a flag, however this doesn't appear to work with copying to .zip, for some reason.
Follow-up question: If it's not possible for the .vbs which I'm using to achieve this, then is there an alternative way, which still utilises calling another file/process(?) (.vbs / .js, or other?) and feeding it the two paths from cmd?
Edit: I'm trying to achieve this without the use of third-party software (e.g. 7zip), and simply using native windows code.
Suppose I am almost 3 months late on this, but if you have powershell version 5 or later, you can simply create a powershell script:
Compress-Archive "C:\Source" "C:\Destination\Data.zip"
or from a batch file:
powershell Compress-Archive "C:\Source" "C:\Destination\Data.zip"
Also see this option

VBA code inside Excel doesn't run when triggered via Scheduler

So the setup on this WinServer 2012 R2 64bit is:
Windows Task Scheduler -> cscript .vbs file -> opening excel and run a sub in the main module
This runs fine in the background when I double click the .vbs file, but when I trigger the .vbs via the task scheduler, excel opens, but doesn't load the file or run the sub (not sure which). The task runs under an domain user that has administration rights on the machine. I use the same user when i try clicking on the .vbs
Code that is being run, in order:
Task scheduler launches:
C:\WINDOWS\system32\cscript.exe "D:\xyz\trigger.vbs"
.vbs does:
Option Explicit
Dim xlApp, xlBook, xlsheets, xlcopy
Set xlApp = CreateObject("Excel.Application")
xlapp.Interactive = False
xlapp.DisplayAlerts = False
xlapp.AskToUpdateLinks = False
xlapp.AlertBeforeOverwriting = False
Set xlBook = xlApp.Workbooks.Open("D:\xyz\excelfile.xlsm")
On Error Resume Next
Call xlBook.Application.Run("Main.Extrnal_Trigger")
xlbook.Saved = True
xlBook.Close
xlApp.Quit
Set xlBook = Nothing
Set xlcopy = Nothing
Set xlApp = Nothing
WScript.Quit(1)
Excel code:
Sub Extrnal_Trigger()
Application.EnableEvents = False
Application.AskToUpdateLinks = False
Application.DisplayAlerts = False
Application.AlertBeforeOverwriting = False
Call update_button
Call MainProgram
Call ReportSave
End Sub
How can I find out where the .vbs or the excel hangs and why? A very similar setup on another machine does run without troubles. It is virtually identical to the code quoted here.
I realize there are several bad practices (like not cleaning up xlapp settings), but I'd like to get the process running before cleaning up.
/edit:
Removing
On Error Resume Next
from the .vbs does not display an error.
/edit2:
I tried reverting as far back as possible.
Option Explicit
Dim fso, f, s, log
Set fso = CreateObject("Scripting.FileSystemObject")
Set log = fso.CreateTextFile("D:\xyz\TESTlog.txt")
log.WriteLine "before fso"
Set f = fso.GetFile("D:\xyz\excel.xlsm")
s = f.Path & " "
s = s & "Created: " & f.DateCreated & " "
s = s & "Last Accessed: " & f.DateLastAccessed & " "
s = s & "Last Modified: " & f.DateLastModified
log.WriteLine "after fso"
log.writeline "fso content"
log.writeline s
This works when being triggered by the task scheduler via cscript.exe.
I will try to modify to log what's happening around the call to the excel file.
/edit3:
Debugging showed that this
Set xlBook = xlApp.Workbooks.Open("D:\xyz\excel.xlsm")
never happens. I put out error numbers and got error 1004 for this call. Still not sure what's the issue, but at least I got an error number now.
/edit4:
error 1004 when trying to run this as a scheduled tasks persists. When I am running it by double clicking the .vbs, everything works.
The key was to create both these folders:
C:\Windows\System32\config\systemprofile\Desktop
and
C:\Windows\SysWOW64\config\systemprofile\Desktop
Excel apparently has troubles running in non-interactive mode when these folders are not present (not sure why). Creating them got rid ofthe 1004 error when opening the workbook via vbs.

VBS slows near the end

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.

How to make vbs message box "always on top"

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.

Resources