VBS Case Statement is failing - vbscript

This case statement is failing...it is like it never even sees it any help would be greatly appreciated.
Dim Runmode
Set objFileToRead = CreateObject("Scripting.FileSystemObject").OpenTextFile("D:\Program Files (x86)\Logility\SPC8.0\Input\FG352F.txt",1)
RunMode = objFileToRead.ReadAll()
objFileToRead.Close
Set objFileToRead = Nothing
MsgBox(RunMode)
select Case RunMode
Case "D"
Set oShell = CreateObject("WSCript.shell")
oShell.run "D:\Scripts\RTL_DAILY.bat"
Case "W"
Set oShell = WScript.CreateObject("WSCript.shell")
oShell.run "D:\Scripts\RTL_WEEKLY.bat"
Case "M"
Set oShell = WScript.CreateObject("WSCript.shell")
oShell.run "D:\Scripts\RTL_MONTHLY.bat"
End Select

Assuming the file contains a single letter like "M" and perhaps an EOL, use .ReadLine() to get rid of the EOL automagically.
In general, a Case Else to catch (and dump) surprises is always a good idea.

Related

Why does this small vbscript to change desktop background work intermittently, not all the time?

A small VBscript in order to change the desktop background automatically, practically for demo purposes:
dim wshShell
dim sUserName
Set wshShell = WScript.CreateObject("WScript.Shell")
Set oShell = CreateObject("WScript.Shell")
currWallPaper = oShell.RegRead("HKCU\Software\Microsoft\InternetExplorer\Desktop\General\Wallpap erSource")
If currWallPaper = "C:\Users\Utsav\Pictures\493889.png" Then
msgbox "OK1"
sWallPaper = "C:\Users\Utsav\Pictures\336180.png"
ElseIf currWallPaper = "C:\Users\Utsav\Pictures\336180.png" Then
sWallPaper = "C:\Users\Utsav\Pictures\1920-1080-278658.png"
Else
sWallPaper = "C:\Users\Utsav\Pictures\493889.png"
End If
' update in registry
oShell.RegWrite "HKCU\Control Panel\Desktop\Wallpaper", sWallPaper
' let the system know about the change
oShell.Run "%windir%\System32\RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters", 1, True
msgbox "done"
This script works only intermittently, i.e. on executing from command line it will change the background only once in about 4-5 attempts. Any ideas explaining the reason for this behaviour would be most welcome.

VbScript to trim trailing pipes off file at 35 pipes

So I was initially writing this in batch, but the number of tokens usable with ASCII were too small, i guess it only allows 26, and I need 35 pipes to remain in my output file.
I am new to VBScript, but basically I want it to read in the original file, do some magic to select the first character in the file to the last 35 pipes (and everything between, even in the space between the two pipes is blank). Then output that file to another file, while retaining the integrity of original.
Here is my code so far:
' **************
' ** Anthony B.
' **************
' ** PipeDropper
' **************
Dim WshShell, oExec
Set wshShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFSO.OpenTextFile("C:\Users\aborgetti\Desktop\Pipe Delimiter Project\oauthrn.cms",1)
Set objOutputFile = objFSO.OpenTextFile("C:\Users\aborgetti\Desktop\Pipe Delimiter Project\output.txt",8,True)
Do until objInputFile.AtEndofStream
strcomputer = objInputFile.ReadLine
strCommand = "dsquery computer -name " & strComputer
Set oExec = WShShell.Exec(strCommand)
If (oExec.Status = 0) Then
If (oExec.stdOut.ReadAll = "") Then
objOutputFile.WriteLine(strComputer)
End If
End If
Loop
objInputFile.Close
objOutputFile.Close
Issues
This line Set oExec = WShShell.Exec(strCommand)
says it can't find the file that's specified...so I'm not sure why that's bad.
And then where do I go from here?
Thanks in advance!
UPDATE
Here is a line that would be in the file, usually anywhere from 10-100 times...
RE|922124607|1 |KimV|HOS99999|Y|N|2014-04-02 15:49:14|2014-04-02 15:49:58|Y|2014-04-02 00:00:00|R9815|01|1 |2014-04-02 00:00:00|493.90||||2016-04-02|N||HOS99999|||06|PROV99999|2014-04-02 15:48:20|2014-04-02||R9815|2014-04-02 00:00:00|2016-04-02 00:00:00||||||98960|06 |08|6|6|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||02|||||||Z4|2014-04-02 15:49:58|04|001|01|***|PMER|***|***|2013-08-01||||||||||||||||||||||||||||||||||||||||
Everything after the last 01 needs to go...so:
|***|PMER|***|***|2013-08-01||||||||||||||||||||||||||||||||||||||||
Should be:
Start of line ... |***|PMER|***|***|2013-08-01
I doubt that your problem
has anything to do with pipes
the code you published is the code that caused the error
There are two ways to get an error 424 "Object required" for a statement like
Set a = b.c(d)
The first (and obvious): b isn't an object. The second: the return value of b.c(d) isn't an object.
Your code condensed:
Set wshShell = CreateObject("WScript.Shell")
strCommand = "hostname"
Set oExec = WShShell.Exec(strCommand)
WScript.Echo oExec.Stdout.Readline()
runs without a problem. A slight change:
Set wshShell = CreateObject("WScript.Shell")
strCommand = "hostname"
Set oExec = WShShel1.Exec(strCommand)
WScript.Echo oExec.Stdout.Readline()
fails with "Object required". Do you spot the typo? Why not let "Option Explicit" help you:
Option Explicit
Dim wshShell : Set wshShell = CreateObject("WScript.Shell")
Dim strCommand : strCommand = "hostname"
Dim oExec : Set oExec = WShShel1.Exec(strCommand)
WScript.Echo oExec.Stdout.Readline()
output:
...\22871772.vbs(4, 18) Microsoft VBScript runtime error: Variable is undefined: 'WShShel1'
If you made sure that no typo caused the problem, you'll have to check whether the variable is changed/assigned to between initialization and use:
Option Explicit
Dim wshShell : Set wshShell = CreateObject("WScript.Shell")
Dim strCommand : strCommand = "hostname"
'...
wShSheLL = "oops"
'...
Dim oExec : Set oExec = WShShell.Exec(strCommand)
WScript.Echo oExec.Stdout.Readline()
again fails with error 424.
Update wrt the pipes:
I'd choose Split() (with count set to #pipes you want + 1) to deal with the trailing pipes:
>> n = 8 + 1
>> s = "|abc123|1*|004|**gobbligook|001|%|2014-01-01|||||||||||||"
>> a = Split(s, "|", n) ' <-- 9th elm get all the junk
>> WScript.Echo UBound(a)
>> a(n - 1) = "" ' <-- zap the junk
>> WScript.Echo Join(a, "|")
>>
8
|abc123|1*|004|**gobbligook|001|%|2014-01-01|
To delete a tail of |'s, a RegExp seems more appropriate:
>> set r = New RegExp
>> r.Pattern = "\|+$"
>> WScript.Echo r.Replace(s, "")
>>
|abc123|1*|004|**gobbligook|001|%|2014-01-01

Store objShell.run in variable

I am trying to store the output from a objShell.run and then display it out.
On Error Resume Next
Set objShell = CreateObject("WScript.Shell")
strPermissionsDirValue = ""
strPermissionsDirValue = objShell.run ("cacls C:\SQL2008")
WScript.Echo VBTab & strPermissionsDirValue
strPermissionsDirValue = ""
When I execute the above I get 0.
The output should be
C:\SQL2008 CREATOR OWNER:(OI)(CI)(IO)F
NT AUTHORITY\SYSTEM:(OI)(CI)F
BUILTIN\Administrators:(OI)(CI)F
The WScript.Shell object will only return numbers, based on exit status of the application you launched.
One way would be to dump the output to a temp file. Change this line..
strPermissionsDirValue = objShell.run ("cacls C:\SQL2008")
To this..
objShell.run "cmd /k cacls C:\SQL2008 > temp.txt"
Then, just read that temp file and in this case, process each line of the cacls output.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInputFile = objFSO.OpenTextFile("temp.txt", 1)
Do While objInputFile.AtEndOfStream = False
strLine = objInputFile.ReadLine
Loop

How to Copy a file that was read from a list

Hello guys I have an issue or issues with my code above
I'm trying to get "sExtension" to be search in a different folder other that the one I'm using to save my script since this script will be use as a Startup Script on many computers
(It works only if I run the script in the same folder "sExtension", "ExtAssign.txt" and sComputername are otherwise it wont find the path)
This is what it should do
Read a file called "ExtAssign.txt" (There is a full list of computer names in that file) and if it find the computer name on that file then it should copy a file with the with the extension number assigned to that computer name from a file server to "C:\" Drive
For this example I'm trying to do this locally, If I can make it then I'll try it from my File Server
Set objFSO = CreateObject("Scripting.FileSystemObject")
set oFso = CreateObject("Scripting.FileSystemObject")
Set objFS = CreateObject("Scripting.FileSystemObject")
Set fso = CreateObject("Scripting.FileSystemObject")
set oShell = WScript.CreateObject("WScript.Shell")
set oShellEnv = oShell.Environment("Process")
Set folder = Fso.GetFolder("C:\Users\XXXXX\Desktop\Test\Extensions\")
Set wshshell = CreateObject("WScript.Shell")
Set objNetwork = CreateObject("WScript.Network")
Set ObjEnv = WshShell.Environment("Process")
Set objFso = WScript.CreateObject("Scripting.FileSystemObject")
Scomputername = ObjEnv("COMPUTERNAME")
Set objFSO = CreateObject("Scripting.FileSystemObject")
set objWShell = wScript.createObject("WScript.Shell")
Dim strFile
'File to scan
strFile = "C:\Users\XXXXX\Desktop\Test\Extensions\Extassign\ExtAssign.txt"
Dim strPattern
'Look for computer name in file
strPattern = scomputername
Set objFso = WScript.CreateObject("Scripting.FileSystemObject")
Set objFile = objFS.OpenTextFile(strFile)
Do Until objFile.AtEndOfStream
Dim strLine
'Read each line and store it in strLine
strLine = objFile.ReadLine
'If the line matches the computer name, save the line to ExtArray
If InStr(strLine,strPattern)>0 Then
Dim ExtArray
'Split the line and separate the extension
ExtArray = Split(strLine,"|", -1, 1)
Dim sExtension
'Save the extension to sExtension
sExtension=ExtArray(1)
End If
Loop
'If the sExtension is empty, computer was not found, send message and terminate script.
If sExtension="" Then
WScript.Echo "ERROR: Computer "& scomputername &" not found in Extension Assignment List, so no extension has been set. Avaya will not be launched. Please contact your IT department for assistance."
Else
'If the sExtension contains a number, Copy that file to C:\ and rename it to Config.xml
fso.CopyFile "C:\Users\XXXXX\Desktop\Test\Extensions\ "& sExtension &"", "C:\Config.xml", True
End If
at the end it if it finds the file sExtension it will rename it to Config.xml but it wont do it unless I run the script in the same folder sExtension and sComputername.
I get File not found error
Thank you in advance and Happy new year!
The culprit is most likely this line:
fso.CopyFile "C:\Users\XXXXX\Desktop\Test\Extensions\ "& sExtension &"", "C:\Config.xml", True
There is a trailing space after the last backslash in the path, so you're creating a path
C:\Users\XXXXX\Desktop\Test\Extensions\ 12345
^
when you actually want a path
C:\Users\XXXXX\Desktop\Test\Extensions\12345
On a more general note: why are you creating 7(!) FileSystemObject instances (replacing one of them three times on top of that)? And 3(!) WScript.Shell instances? You don't even use most of them, not to mention that you don't need the Shell object in the first place. You only use it for determining the computer name, which could be done just fine using the WScript.Network object (that you don't use at all).
Also, please don't ever use comments like this:
'Read each line and store it in strLine
strLine = objFile.ReadLine
It's quite obvious that you read each line and assign it to the variable strLine. Comments shouldn't rephrase what you're doing (the code already does that, at least when you're using speaking variable and function names), but why you're doing it, i.e. what the purpose of a particular code section is.
Your code could be reduced to something as simple as this:
Set fso = CreateObject("Scripting.FileSystemObject")
Set net = CreateObject("WScript.Network")
computername = net.ComputerName
foldername = "C:\Users\XXXXX\Desktop\Test\Extensions"
filename = fso.BuildPath(foldername, "Extassign\ExtAssign.txt")
Set f = fso.OpenTextFile(filename)
Do Until f.AtEndOfStream
line = f.ReadLine
If InStr(line, computername) > 0 Then
arr = Split(line, "|", -1, 1)
If UBound(arr) >= 1 Then extension = arr(1)
End If
Loop
f.Close
If IsEmpty(extension) Then
WScript.Echo "ERROR: Computer "& computername &" not found in ..."
Else
fso.CopyFile fso.BuildPath(foldername, extension), "C:\Config.xml", True
End If

Use clipboard from VBScript

I am looking for a method to place some text onto the clipboard with VBScript. The VBScript in question will be deployed as part of our login script. I would like to avoid using anything that isn't available on a clean Windows XP system.
Edit:
In answer to the questions about what this is for.
We wanted to encourage users inside our organization to use the file server to transfer documents instead of constantly sending attachments by email. One of the biggest barriers to this is that it isn't always obvious to people what the correct network path is to a file/folder. We developed a quick script, and attached it to the Windows context menu so that a user can right click on any file/folder, and get a URL that they can email to someone within our organization.
I want the URL displayed in the dialog box to also be placed onto the clipboard.
GetNetworkPath
Another solution I have found that isn't perfect in my opinion, but doesn't have the annoying security warnings is to use clip.exe from a w2k3 server.
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo hello world | clip", 0, TRUE
Example with a multiline string as per question below :
Link1
Dim string
String = "text here" &chr(13)& "more text here"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo " & String & " | clip", 0, TRUE
Using Microsoft's clip.exe is the closest to having a clean Windows XP system solution. However you don't have to call CMD.EXE to host it in order to use it. You can call it directly and write to its input stream in your script code. Once you close the input stream clip.exe will write the contents straight to the clipboard.
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("clip")
Set oIn = oExec.stdIn
oIn.WriteLine "Something One"
oIn.WriteLine "Something Two"
oIn.WriteLine "Something Three"
oIn.Close
If you need to wait for clip to be finished before your script can continue processing then add
' loop until we're finished working.
Do While oExec.Status = 0
WScript.Sleep 100
Loop
And don't forget to release your objects
Set oIn = Nothing
Set oExec = Nothing
The closest solution I have found so far is a method to use IE to get and set stuff on the clipboard. The problem with this solution is the user gets security warnings. I am tempted to move 'about:blank' to the local computer security zone so I don't get the warnings, but I am not sure what the security implications of that would be.
Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.document.parentwindow.clipboardData.SetData "text", "Hello This Is A Test"
objIE.Quit
http://www.microsoft.com/technet/scriptcenter/resources/qanda/dec04/hey1215.mspx
No security warnings, full let and get access:
'create a clipboard thing
Dim ClipBoard
Set Clipboard = New cClipBoard
ClipBoard.Clear
ClipBoard.Data = "Test"
Class cClipBoard
Private objHTML
Private Sub Class_Initialize
Set objHTML = CreateObject("htmlfile")
End Sub
Public Sub Clear()
objHTML.ParentWindow.ClipboardData.ClearData()
End Sub
Public Property Let Data(Value)
objHTML.ParentWindow.ClipboardData.SetData "Text" , Value
End Property
Public Property Get Data()
Data = objHTML.ParentWindow.ClipboardData.GetData("Text")
End Property
Private Sub Class_Terminate
Set objHTML = Nothing
End Sub
End Class
Example Usage.
' Create scripting object
Dim WShell, lRunUninstall
Set WShell = CreateObject("WScript.Shell")
WShell.sendkeys "^c"
WScript.Sleep 250
bWindowFound = WShell.AppActivate("Microsoft Excel")
WShell.sendkeys ClipBoard.Data
To avoid the security warnings associated with Internet Explorer and clipboard access, I would recommend you use the Word application object and its methods to put your data onto the clipboard. Of course you can only use this on a machine that has MS Word installed, but these days that's most of them. (*In spite of the fact that you asked for stuff on a 'clean' system :) *)
' Set what you want to put in the clipboard '
strMessage = "Imagine that, it works!"
' Declare an object for the word application '
Set objWord = CreateObject("Word.Application")
' Using the object '
With objWord
.Visible = False ' Don't show word '
.Documents.Add ' Create a document '
.Selection.TypeText strMessage ' Put text into it '
.Selection.WholeStory ' Select everything in the doc '
.Selection.Copy ' Copy contents to clipboard '
.Quit False ' Close Word, don't save '
End With
You can find detail on the MS Word application object and its methods here: http://msdn.microsoft.com/en-us/library/aa221371(office.11).aspx
Microsoft doesn't give a way for VBScript to directly access the clipboard. If you do a search for 'clipboard'on this site you'll see:
Although Visual Basic for Applications supports the Screen, Printer, App, Debug, Err, and Clipboard objects, VBScript supports only the Err object. Therefore, VBScript does not allow you to access such useful objects as the mouse pointer or the clipboard. You can, however, use the Err object to provide runtime error handling for your applications.
So using notepad indirectly is probably about the best you'll be able to do with just VBScript.
Here's another version of using the "clip" command, which avoids adding a carriage return, line feed to the end of the string:
strA= "some character string"
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "cmd /C echo . | set /p x=" & strA & "| c:\clip.exe", 2
s = "String: """ & strA & """ is on the clipboard."
Wscript.Echo s
I've only tested this in XP. clip.exe was downloaded from Link and placed in C:\.
I've found a way to copy multi line information to clipboard by vbscript/cmd.
Sequence:
with VBS generate the final "formatted string" that you need copy to clipboard
generate a (txt) file with the "formatted string"
use type command from cmd to paste information to clip by pipe
Example script:
Function CopyToClipboard( sInputString )
Dim oShell: Set oShell = CreateObject("WScript.Shell")
Dim sTempFolder: sTempFolder = oShell.ExpandEnvironmentStrings("%TEMP%")
Dim sFullFilePath: sFullFilePath = sTempFolder & "\" & "temp_file.txt"
Const iForWriting = 2, bCreateFile = True
Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
With oFSO.OpenTextFile(sFullFilePath, iForWriting, bCreateFile)
.Write sInputString
.Close
End With
Const iHideWindow = 0, bWaitOnReturnTrue = True
Dim sCommand: sCommand = "CMD /C TYPE " & sFullFilePath & "|CLIP"
oShell.Run sCommand, iHideWindow, bWaitOnReturnTrue
Set oShell = Nothing
Set oFSO = Nothing
End Function
Sub Main
Call CopyToClipboard( "Text1" & vbNewLine & "Text2" )
End Sub
Call Main
The easiest way is to use built-in mshta.exe functionality:
sText = "Text Content"
CreateObject("WScript.Shell").Run "mshta.exe ""javascript:clipboardData.setData('text','" & Replace(Replace(sText, "\", "\\"), "'", "\'") & "');close();""", 0, True
To put to clipboard a string containing double quote char ", use the below code:
sText = "Text Content and double quote "" char"
CreateObject("WScript.Shell").Run "mshta.exe ""javascript:clipboardData.setData('text','" & Replace(Replace(Replace(sText, "\", "\\"), """", """"""), "'", "\'") & "'.replace('""""',String.fromCharCode(34)));close();""", 0, True
Take a look at this post. It describes a hacky approach to read from the clipboard, but I imagine it could be adapted to also write to the clipboard as well, such as changing the Ctrl+V to Ctrl+A then Ctrl+C.
I devised another way to use IE and yet avoid security warnings...
By the way.. this function is in JavaScript.. but u can easily convert it to VBScript..
function CopyText(sTxt) {
var oIe = WScript.CreateObject('InternetExplorer.Application');
oIe.silent = true;
oIe.Navigate('about:blank');
while(oIe.ReadyState!=4) WScript.Sleep(20);
while(oIe.document.readyState!='complete') WSript.Sleep(20);
oIe.document.body.innerHTML = "<textarea id=txtArea wrap=off></textarea>";
var oTb = oIe.document.getElementById('txtArea');
oTb.value = sTxt;
oTb.select();
oTb = null;
oIe.ExecWB(12,0);
oIe.Quit();
oIe = null;
}
Here is Srikanth's method translated into vbs
function SetClipBoard(sTxt)
Set oIe = WScript.CreateObject("InternetExplorer.Application")
oIe.silent = true
oIe.Navigate("about:blank")
do while oIe.ReadyState <> 4
WScript.Sleep 20
loop
do while oIe.document.readyState <> "complete"
WScript.Sleep 20
loop
oIe.document.body.innerHTML = "<textarea id=txtArea wrap=off></textarea>"
set oTb = oIe.document.getElementById("txtArea")
oTb.value = sTxt
oTb.select
set oTb = nothing
oIe.ExecWB 12,0
oIe.Quit
Set oIe = nothing
End function
function GetClipBoard()
set oIe = WScript.CreateObject("InternetExplorer.Application")
oIe.silent = true
oIe.Navigate("about:blank")
do while oIe.ReadyState <> 4
WScript.Sleep 20
loop
do while oIe.document.readyState <> "complete"
WScript.Sleep 20
loop
oIe.document.body.innerHTML = "<textarea id=txtArea wrap=off></textarea>"
set oTb = oIe.document.getElementById("txtArea")
oTb.focus
oIe.ExecWB 13,0
GetClipBoard = oTb.value
oTb.select
set oTb = nothing
oIe.Quit
Set oIe = nothing
End function
In your Class ClipBoard, neither the Clear sub nor the Let Data sub work. I mean they have no effect on Windows Clipboard. Actually, and ironically so, the only sub that works is the one you have not included in your example, that is Get Data! (I have tested this code quite a few times.)
However, it's not your fault. I have tried to copy data to clipboard with ClipboardData.SetData and it's impossible. At least not by creating an "htmlfile" object. Maybe it works by creating an instance of "InternetExplorer.Application" as I have seen in a few cases, but I have not tried it. I hate creating application instances for such simple tasks!
Alkis
If it's just text can't you simply create a text file and read in the contents when you need it?
Another alternative and clearly a kludge, would be to use the SendKeys() method.
No security warnings and no carriage return at the end of line
' value to put in Clipboard
mavaleur = "YEAH"
' current Dir
path = WScript.ScriptFullName
GetPath = Left(path, InStrRev(path, "\"))
' Put the value in a file
Set objFSO=CreateObject("Scripting.FileSystemObject")
outFile=GetPath & "fichier.valeur"
Set objFile = objFSO.CreateTextFile(outFile,True)
objFile.Write mavaleur
objFile.Close
' Put the file in the Clipboard
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c clip < " & outFile, 0, TRUE
' Erase the file
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile outFile

Resources