vbscript to check if a window is open using wildcard - vbscript

I would like to check if a window is open using wildcard in vbscript. I was able to find the code below:
Set oShell = CreateObject("WScript.Shell")
If oShell.AppActivate("Untitled - Notepad") Then
WScript.Sleep 500
End If
But i would like to use a wildcard on the window title. I tried using * and % but it's not working. Any help is appreciated.
If oShell.AppActivate("*Notepad*") Then
Updates guys.. I was able to find a solution but it is still open if someone can simplify this. Thank you.
Set Word = CreateObject("Word.Application")
Set Tasks = Word.Tasks
isFound = False
For i = 1 to 5
For Each Task in Tasks
checkVal = 0
If Task.Visible Then
checkVal = inStr(UCase(Task.name), UCase("outlook"))
If checkVal <> 0 Then
isFound = True
Exit For
End If
End If
Next
If isFound = True Then
Exit For
End If
WScript.Sleep 1000
Next
Word.Quit
msgbox ("Is the Window Found? - " & isFound)

Check out this method versus creating a word doc. That method requires a dependency of having office installed. This uses only native Windows libraries.
First function: findwindowtitle
Executes the Tasklist command to enumerate and filter down the list of titles. Then fires off the regex parser to match your string against the leftover values from tasklist.
Second function: matchtitle Then it proceeds to use convert your wildcard into a regular expression of the [a-zA-Z0-9.- ] which is alphanumeric including spaces. Kind of required for the wildcard and allowed characters for windows files to work.
MysearchString = "*Notepad"
processtitle = findwindowtitle(MysearchString)
wscript.echo "My search found window title: '" & processtitle & "'"
'do something with processtitle
function findwindowtitle(srchstr)
filtersrchstr = replace(srchstr, "*", "")
strcommand = "tasklist /v | find /i """ & filtersrchstr & """"
cmdout = CreateObject("Wscript.Shell").Exec("cmd /c """ & strcommand & " 2>&1 """).stdout.readall
wscript.sleep 500
findwindowtitle = matchtitle(srchstr, cmdout)
End Function
Function matchtitle(srchstr, input)
matchtitle = false
if instr(1, srchstr, "*", 1) <> 0 Then
filtersrchstr = replace(srchstr, "*", "")
filterstrpatt = replace(srchstr, "*", "[a-zA-Z0-9\.- ]*")
end if
Set regex = CreateObject("VBScript.RegExp")
regex.MultiLine = True
regex.Global = True
regex.IgnoreCase = True
regex.Pattern = "(?:.*)(?:\d\d?\d?:\d\d:\d\d\s)(\b" & filterstrpatt & "\b)"
Set matches = regex.Execute(input)
for m = 0 to matches.count - 1
Set SubMatches = matches.item(m).SubMatches
for i = 0 to (Submatches.count - 1)
if instr(1, Submatches.item(i), filtersrchstr, 1) <> 0 then matchtitle = Submatches.item(i)
Next
Next
if (matchtitle = false) then
wscript.echo "Could not find process with title matching, '" & srchstr & "'"
wscript.quit
end if
End Function

Related

VBScript is causing WINWORD.EXE and WSCRIPT.exe to hang up

I have this .vbs script that I use to automate the creation of a .doc file.
This script runs fine when launched from a .bat, or directly from the command line. But I have an external program launching this script and it becomes hung up. When this happens it has a bunch of WINWORD.exe and WSCRIPT.exe entries in the task manager.
Is there anything obviously wrong with this code that could cause issues?
Const wdReplaceAll = 2
Const workPath = "d:\work"
Const template = "template\template.doc"
UniqueId = Wscript.Arguments(0)
If Wscript.Arguments.Named.Exists("Tokens") Then
strTokens = Wscript.Arguments.Named.Item("Tokens")
End If
If Wscript.Arguments.Named.Exists("Values") Then
strValues = Wscript.Arguments.Named.Item("Values")
End If
arrToken = Split(strTokens,"|")
arrValue = Split(strValues,"|")
if UBound(arrToken) = UBound(arrValue) Then
CreateFax UniqueId, arrToken, arrValue
else
Wscript.Echo "Tokens and Values must be same length"
Wscript.Echo "Tokens: " & UBound(arrToken) + 1 & " Values: " & UBound(arrValue) + 1
end if
Sub CreateFax(UniqueId, arrToken, arrValue)
Set objWord = CreateObject("Word.Application")
objWord.Visible = True
objWord.Activate
objWord.DisplayAlerts = 0
Set objDoc = objWord.Documents.Open(workPath & "\" & template)
for i = 0 to UBound(arrToken)
FindAndReplace objWord.Selection, arrToken(i), arrValue(i)
next
objDoc.SaveAs(workPath & "\" & UniqueId & ".doc")
objWord.Quit
Set objSelection = Nothing
Set objDoc = Nothing
Set objWord = Nothing
End Sub
Sub FindAndReplace (objSelection, strFind, strReplace)
objSelection.Find.Text = strFind
objSelection.Find.Forward = TRUE
objSelection.Find.MatchWholeWord = TRUE
objSelection.Find.Replacement.Text = strReplace
objSelection.Find.Execute ,,,,,,,,,,wdReplaceAll
End Sub
Even though StackOverflow isn't a debugging service...
No, there is not anything obviously wrong.
Have a look at the mentioned externel program, the automated process and debug them.
I have edited your question and reformatted the code block. For potential answerers it's always more pleasant to find a well described problem, nice formatting and not too much to scroll.

remove nul characters from text file using vbs

I have text files that are approximately 6MB in size. There are some lines that contain the NULL (Chr(0))character that I would like to remove.
I have two methods to do this: using Asc()=0 but this takes approximately 50s to complete, the other method uses InStr (line, Chr(0)) =0 (fast ~ 4sec)but the results remove vital info from the lines which contain the NULL characters.
First line of text file as example:
##MMCIBN.000NULL7NULL076059NULL7653NULL1375686349NULL2528NULL780608NULL10700NULL\NULL_NC_ACT.DIR\CFG_RESET.INI
First method (works but VERY slow)
function normalise (textFile )
Set fso = CreateObject("Scripting.FileSystemObject")
writeTo = fso.BuildPath(tempFolder, saveTo & ("\Output.arc"))
Set objOutFile = fso.CreateTextFile(writeTo)
Set objFile = fso.OpenTextFile(textFile,1)
Do Until objFile.AtEndOfStream
strCharacters = objFile.Read(1)
If Asc(strCharacters) = 0 Then
objOutFile.Write ""
nul = true
Else
if nul = true then
objOutFile.Write(VbLf & strCharacters)
else
objOutFile.Write(strCharacters)
end if
nul = false
End If
Loop
objOutFile.close
end function
The output looks like this:
##MMCIBN.000
7
076059
7653
1375686349
2528
780608
10700
\
_NC_ACT.DIR\CFG_RESET.INI
Second method code:
filename = WScript.Arguments(0)
Set fso = CreateObject("Scripting.FileSystemObject")
sDate = Year(Now()) & Right("0" & Month(now()), 2) & Right("00" & Day(Now()), 2)
file = fso.BuildPath(fso.GetFile(filename).ParentFolder.Path, saveTo & "Output " & sDate & ".arc")
Set objOutFile = fso.CreateTextFile(file)
Set f = fso.OpenTextFile(filename)
Do Until f.AtEndOfStream
line = f.ReadLine
If (InStr(line, Chr(0)) > 0) Then
line = Left(line, InStr(line, Chr(0)) - 1) & Right(line, InStr(line, Chr(0)) + 1)
end if
objOutFile.WriteLine line
Loop
f.Close
but then the output is:
##MMCIBN.000\CFG_RESET.INI
Can someone please guide me how to remove the NULLS quickly without losing information. I have thought to try and use the second method to scan for which line numbers need updating and then feed this to the first method to try and speed things up, but quite honestly I have no idea where to even start doing this!
Thanks in advance...
It looks like the first method is just replacing each NULL with a newline. If that's all you need, you can just do this:
Updated:
OK, sounds like you need to replace each set of NULLs with a newline. Let's try this instead:
strText = fso.OpenTextFile(textFile, 1).ReadAll()
With New RegExp
.Pattern = "\x00+"
.Global = True
strText = .Replace(strText, vbCrLf)
End With
objOutFile.Write strText
Update 2:
I think the Read/ReadAll methods of the TextStream class are having trouble dealing with the mix of text and binary data. Let's use an ADO Stream object to read the data instead.
' Read the "text" file using a Stream object...
Const adTypeText = 2
With CreateObject("ADODB.Stream")
.Type = adTypeText
.Open
.LoadFromFile textFile
.Charset = "us-ascii"
strText = .ReadText()
End With
' Now do our regex replacement...
With New RegExp
.Pattern = "\x00+"
.Global = True
strText = .Replace(strText, vbCrLf)
End With
' Now write using a standard TextStream...
With fso.CreateTextFile(file)
.Write strText
.Close
End With
I tried this method (update2) for reading a MS-Access lock file (Null characters terminated strings in 64 byte records) and the ADODB.Stream didn't want to open an already in use file. So I changed that part to :
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.GetFile(Lfile)
z = f.Size
set ts = f.OpenAsTextStream(ForReading, 0) 'TristateFalse
strLog = ts.Read(z)
ts.Close
set f = nothing
' replace 00 with spaces
With New RegExp
.Pattern = "\x00+"
.Global = True
strLog = .Replace(strLog, " ")
End With
' read MS-Access computername and username
for r = 1 to len(strLog) step 64
fnd = trim(mid(strLog,r, 32)) & ", " & trim(mid(strLog,r+32, 32)) & vbCrLf
strRpt = strRpt & fnd
next

subscript out of range error in vbscript

Can someone look at the below script and tell me why it's throwing this error subscript out of range error in vbscript ..In the text file there are two entries it writes to the file correctly but then it throws an error while exiting the loop so it never calls the other function..I think it's trying to run 3 times but there are just 2 entries in the text file
The text file is in this format
Format.css Shared
Design.css Shared
Dim strInputPath1
Dim txsInput1,txsOutput
Dim FSO
Dim Filename
Set FSO = CreateObject("Scripting.FileSystemObject")
strOutputPath = "C:\txt3.txt"
Set txsOutput = FSO.CreateTextFile(strOutputPath)
Set re = New RegExp
re.Pattern = "\s+"
re.Global = True
Set f = FSO.OpenTextFile("C:\Users\spadmin\Desktop\Main\combination.txt")
Do Until f.AtEndOfStream
tokens = Split(Trim(re.Replace(f.ReadLine, " ")))
extension = Split(tokens(0),".")
strInputPath1 = "C:\inetpub\wwwroot\Test\files\" & tokens(1) & "\" & extension(1) & "\" & tokens(0)
Set txsInput1 = FSO.OpenTextFile(strInputPath1, 1)
WScript.Echo strInputPath1
txsOutput.Writeline txsInput1.ReadAll
Loop
WScript.Echo "Calling"
txsInput1.Close
txsOutput.Close
f.Close
Call CreateCSSFile()
''''''''''''''''''''''''''''''''''''
' Merge Css Files
''''''''''''''''''''''''''''''''''''
Sub CreateCSSFile()
WScript.Echo "Called"
Dim FilenameCSS
Dim strInputPathCSS
Dim txsInputCSS,txsOutputCSS
Dim FSOCSS
Set FSOCSS = CreateObject("Scripting.FileSystemObject")
strOutputPathCSS = "C:\txt4.txt"
Set txsOutputCSS = FSOCSS.CreateTextFile(strOutputPath)
Set re = New RegExp
re.Pattern = "\s+"
re.Global = True
Set fCSS = FSOCSS.OpenTextFile("C:\Users\spadmin\Desktop\TestingTheWebService\combination.txt")
Do Until fCSS.AtEndOfStream
tokensCSS = Split(Trim(re.Replace(fCSS.ReadLine, " ")))
extensionCSS = Split(tokensCSS(0),".")
strInputPathCSS = "C:\inetpub\wwwroot\EpsShared\c\" & tokensCSS(1) & "\" & extensionCSS(1) & "\" & tokensCSS(0)
Set txsInputCSS = FSOCSS.OpenTextFile(strInputPathCSS, 1)
txsOutputCSS.Writeline txsInputCSS.ReadAll
Loop
fCSS.Close
txsInputCSS.Close
txsOutputCSS.Close
Set FSOCSS = Nothing
End Sub
If your file contains trailing blank lines, applying Split() may return arrays with less than 2 elements. In that case token(1) should throw a 'subscript out of range' error.
You should always check, if Split() workes as expected:
tokens = Split(Trim(re.Replace(f.ReadLine, " ")))
If 1 = UBound(tokens) Then
extension = Split(tokens(0),".")
If 1 = UBound(extension) Then
strInputPath1 = "..." & tokens(1) & "..."
Else
... parse error ...
End If
Else
... parse error or just trailing blank lines? ...
End If

Trying to use Shell object and FileSystemObject in VBScript for file manipulation

I am trying to recursively loop through hundreds of directories, and thousands of JPG files to gather sort the files in new folders by date. So far, I am able to individually GetDetailsOf the files using the Shell NameSpace object, and I am also able to recursively loop through directories using the FileSystemObject. However, when I try to put them together in functions, etc, I am getting nothing back when I try to get the DateTaken attribute from the photo.
Here is my code so far:
sFolderPathspec = "C:\LocationOfFiles"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objDir = objFSO.GetFolder(sFolderPathspec)
Dim arrFiles()
getInfo(objDir)
Sub getInfo(pCurrentDir)
fileCount = 0
For Each strFileName In pCurrentDir.Files
fileCount = fileCount + 1
Next
ReDim arrFiles(fileCount,2)
i=0
For Each aItem In pCurrentDir.Files
wscript.Echo aItem.Name
arrFiles(i,0) = aItem.Name
strFileName = aItem.Name
strDir = pCurrentDir.Path
wscript.echo strDir
dateVar = GetDatePictureTaken(strFileName, strDir)
'dateVar = Temp2 & "_" & Temp3 & "_" & Temp1
arrFiles(i,1) = dateVar
WScript.echo i & "." & "M:" & monthVar & " Y:" & yearVar
WScript.echo i & "." & strFileName & " : " & arrFiles(i,1) & " : " & dateVar
i=i+1
Next
For Each aItem In pCurrentDir.SubFolders
'wscript.Echo aItem.Name & " passing recursively"
getInfo(aItem)
Next
End Sub
Function GetDatePictureTaken(strFileName, strDir)
Set objShell = CreateObject ("Shell.Application")
Set objCurrFolder = objShell.Namespace(strDir)
'wscript.Echo cstr(objCurrFolder.GetDetailsOf(strFileName, 12))
strFileNameDate = cstr(objCurrFolder.GetDetailsOf(strFileName, 12))
strFileNameDate = CleanNonDisplayableCharacters(strFileNameDate)
arrDate = split(strFileNameDate, "/")
'''FAILS HERE WITH A SUBSCRIPT OUT OF RANGE ERROR SINCE IT GETS NULL VALUES BACK FROM THE GET DETAILS OF FUNCTION'''
monthVar = arrDate(0)
yearVar = arrDate(1)
dayVar = arrDate(2)
GetDatePictureTaken = monthVar & "\" & dayVar & "\" & yearVar
End Function
Function CleanNonDisplayableCharacters(strInput)
strTemp = ""
For i = 1 to len(strInput)
strChar = Mid(strInput,i,1)
If Asc(strChar) < 126 and not Asc(strChar) = 63 Then
strTemp = strTemp & strChar
End If
Next
CleanNonDisplayableCharacters = strTemp
End Function
The "Subscript out of range" error when accessing arrDate(0) is caused by arrDate being empty (UBound(arrDate) == -1). As a Split on a non-empty string will return an array, even if the separator is not found, and an attempt to Split Null will raise an "Invalid use of Null" error, we can be sure that strFileNameDate is "".
Possible reason for that:
The index of "Date Picture Taken" is 25 (XP) and not 12 (Win 7) - or whatever came to Mr. Gates' mind for Win 8.
The DPT property is not filled in.
Your cleaning function messed it up.
You have to test for strFileNameDate containing a valid date and decide where to put the files without a valid DPT.
P.S. Instead of doing the recursive loopings, you should consider to use
dir /s/b path\*.jpg > pictures.txt
and to process that file.

To run two or more .VBS script parallely

I have two .vbs file say a.vbs and b.vbs.Now both are written for the same Excel,but would work on 2 different sheets.So can we run those in parallel?
EDIT
a.vbs will update sheet2 and b.vbs will update sheet3.But for both source sheet is sheet1.
Please advice how to set such environment
CODE A
Option Explicit
Dim objExcel1
Dim strPathExcel1
Dim objSheet1,objSheet2
Dim IntRow1,IntRow2
Dim ColStart
Set objExcel1 = CreateObject("Excel.Application")'Object for Condition Dump
strPathExcel1 = "D:\AravoVB\Copy of Original Scripts\CopyofGEWingtoWing_latest_dump_21112012.xls"
objExcel1.Workbooks.open strPathExcel1
Set objSheet1 = objExcel1.ActiveWorkbook.Worksheets(1)
Set objSheet2 = objExcel1.ActiveWorkbook.Worksheets("Bad Data")
objExcel1.ScreenUpdating = False
objExcel1.Calculation = -4135 'xlCalculationManual
IntRow2=2
IntRow1=4
Do Until IntRow1 > objSheet1.UsedRange.Rows.Count
ColStart = objExcel1.Application.WorksheetFunction.Match("Parent Business Process ID", objSheet1.Rows(3), 0) + 1
Do Until ColStart > objSheet1.UsedRange.Columns.Count And objSheet1.Cells(IntRow1,ColStart) = ""
If objSheet1.Cells(IntRow1,ColStart + 1) > objSheet1.Cells(IntRow1,ColStart + 5) And objSheet1.Cells(IntRow1,ColStart + 5) <> "" Then
objSheet1.Range(objSheet1.Cells(IntRow1,1),objSheet1.Cells(IntRow1,objSheet1.UsedRange.Columns.Count)).Copy
objSheet2.Range(objSheet2.Cells(IntRow2,1),objSheet2.Cells(IntRow2,objSheet1.UsedRange.Columns.Count)).PasteSpecial
IntRow2=IntRow2+1
Exit Do
End If
ColStart=ColStart+4
Loop
IntRow1=IntRow1+1
Loop
objExcel1.ScreenUpdating = True
objExcel1.Calculation = -4105 'xlCalculationAutomatic
CODE B
Option Explicit
Dim objExcel1
Dim strPathExcel1
Dim objSheet1,objSheet2
Dim IntRow1,IntRow2
Dim Flag
Dim IntColTemp,IntRowTemp
Dim Strcmp1,Strcmp2
Flag=0
IntColTemp=1
IntRowTemp=3
Set objExcel1 = CreateObject("Excel.Application")'Object for Condition Dump
If Err.Number <> 0 Then
On Error GoTo 0
Wscript.Echo "Excel application not found."
Wscript.Quit
End If
strPathExcel1 = "D:\VA\CopyofGEWingtoWing_latest_dump_21112012.xls"
objExcel1.Workbooks.open strPathExcel1
Set objSheet1 = objExcel1.ActiveWorkbook.Worksheets(1)
Set objSheet2 = objExcel1.ActiveWorkbook.Worksheets(2)
IntRow1=4
IntRow2=1
Do While objSheet1.Cells(IntRow1, 1).Value <> ""
objSheet2.Cells(IntRow2, 1).Value = objSheet1.Cells(IntRow1, 1).Value
IntColTemp=1
Flag=0
'This will travarse to the Parent Business Process ID column horizantally in the excel.
Do While Flag=0
If objSheet1.Cells(IntRowTemp,IntColTemp).Value="Parent Business Process ID" Then
Flag=1
End If
IntColTemp=IntColTemp+1
Loop
IntColTemp=IntColTemp-1
'MsgBox(IntColTemp)
Strcmp1=trim(objSheet1.Cells(IntRow1, 1).Value)
Strcmp2=trim(objSheet1.Cells(IntRow1,IntColTemp).Value)
If Strcmp1=Strcmp2 Then
objSheet2.Cells(IntRow2, 2).Value="Parent"
Else
objSheet2.Cells(IntRow2, 2).Value="child"
End If
IntRow1=IntRow1+1
IntRow2=IntRow2+1
Loop
Working on two different sheets should be possible by putting something like this in both of your scripts:
strPathExcel1 = "D:\CopyofGEWingtoWing_latest_dump_21112012.xls"
On Error Resume Next
Set objExcel1 = GetObject(, "Excel.Application") ' attach to running instance
If Err.Number = 429 Then ' if that fails
Err.Clear
Set objExcel1 = CreateObject("Excel.Application") ' create new instance
If Err Then ' if that still fails
WScript.Echo Err.Description & " (0x" & Hex(Err.Number) & ")"
WScript.Quit 1 ' report error and terminate
End If
objExcel1.Workbooks.Open strPathExcel1
End If
On Error Goto 0
However, I doubt that this approach would gain you enough performance to justify the additional complexity.
In CODE A replace the lines
Set objExcel1 = CreateObject("Excel.Application")'Object for Condition Dump
strPathExcel1 = "D:\AravoVB\Copy of Original Scripts\CopyofGEWingtoWing_latest_dump_21112012.xls"
objExcel1.Workbooks.open strPathExcel1
with the above code block.
In CODE B replace the lines
Set objExcel1 = CreateObject("Excel.Application")'Object for Condition Dump
If Err.Number <> 0 Then
On Error GoTo 0
Wscript.Echo "Excel application not found."
Wscript.Quit
End If
strPathExcel1 = "D:\VA\CopyofGEWingtoWing_latest_dump_21112012.xls"
objExcel1.Workbooks.open strPathExcel1
with the above code block.

Resources