I am trying to connect command prompt through VB script and further its connecting with Oracle enviroment to execute some reports of Oracle discoverer.
But the problem is with this VB script only.
line 2: for establishing the connection.
line 7:fetching the current REQUEST_ID.
line 16:XXDIS_EXPORT_CMD_V is a view and cmd is a column.which select a value like this for corresponding REQUEST_ID.
/CONNECT DISCADMIN:"FAI Financials Intelligence"/discbi#deverp /OPENDB "1 Scheduling" /SHEET "Sheet_1" /EXPORT HTML o27673334.out /LOGFILE l27673334.log /BATCH
In the end i want to execute this cmd using VBScript.
Error coming :
"In line 32 tkgoShell was not
recognized"
This is My code:
' Process job
Set objADO =CreateObject("ADODB.Connection")
objADO.Open "Driver={Microsoft ODBC for Oracle}; CONNECTSTRING=deverp; UID=apps; PWD=apps11i;"
MsgBox "Connection Established to Server.", vbExclamation + vbOKOnly, "System"
Do While True
' Check if there is a job to process
Set moRS=objADO.execute("SELECT apps.xxdis_schedule_pkg.start_job REQUEST_ID FROM dual")
moRS.MoveFirst
msRequest = moRS("REQUEST_ID")
'MsgBox msRequest,msRequest
' If no jobs then exit
' If msRequest = "0" Then
Exit Do
' End If
loop
Set moRS=objADO.execute("SELECT cmd EXPORT_CMD FROM apps.xxdis_export_cmd_v " & _
"WHERE request_id = " & msRequest)
MsgBox msRequest,msRequest
moRS.MoveFirst
msExpCmd = moRS("EXPORT_CMD")
' write command into a temporary file
msCmdFile = "r" & msRequest & ".cmd"
dim moOutputStream,filesys,msCommand
Set filesys = CreateObject("Scripting.FileSystemObject")
Set moOutputStream = filesys.CreateTextFile(msCmdFile, True)
' Substitute $SAMBA$ and $TNS$ locally configured variables
moOutputStream.Write Replace(Replace(msCmd, "$SAMBA$", gsOutDir),_
"$TNS$", gsInstance) & vbCRLF
moOutputStream.Close
' Call Discoverer to process the command
msCommand = gsBinDir & gsDiscoExe & " /EUL " & gsEUL & " /CMDFILE " & msCmdFile
Call tkgoShell.Run (msCommand, 1, true)
If I understand your code correctly I can't see anywhere where you're actually creating the tkgoShell.
Try inserting the following 2 rows before your last line:
Dim tkgoShell
Set tkgoShell = WScript.CreateObject ("WScript.Shell")
See here for more information about Shell.Run.
Related
I am using a VBScript to login automatically into SAP GUI.
It opens automatically the SAP GUI window, it loads the SAP server, but it doesn't populate automatically the user and password fields (remain blank).
It also gives a script error on line 52, char 4:
The enumerator of the collection cannot find en element with the specified index.
The code is the following:
REM The following script was written to log into the SAP server automatically.
REM To view historical information and credit for this script please see
REM the following thread on the SAP Community Network:
REM http://scn.sap.com/thread/3763970
REM This script was last updated by Paul Street on 7/1/15
REM Directives
Option Explicit
REM Variables! Must declare before using because of Option Explicit
Dim WSHShell, SAPGUIPath, SID, InstanceNo, WinTitle, SapGuiAuto, application, connection, session
REM Main
Set WSHShell = WScript.CreateObject("WScript.Shell")
If IsObject(WSHShell) Then
REM Set the path to the SAP GUI directory
SAPGUIPath = "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\"
REM Set the SAP system ID
SID = "eaiserver.domain.com"
REM Set the instance number of the SAP system
InstanceNo = "38"
REM Starts the SAP GUI
WSHShell.Exec SAPGUIPath & "SAPgui.exe " & SID & " " & _
InstanceNo
REM Set the title of the SAP GUI window here
WinTitle = "SAP"
While Not WSHShell.AppActivate(WinTitle)
WScript.Sleep 250
Wend
Set WSHShell = Nothing
End If
REM Remove this if you need to test the above script and want a message box at the end launching the login screen.
REM MsgBox "Here now your script..."
If Not IsObject(application) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(connection) Then
Set connection = application.Children(0)
End If
If Not IsObject(session) Then
Set session = connection.Children(0)
End If
If IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End If
session.findById("wnd[0]").maximize
session.findById("wnd[0]/usr/txtRSYST-MANDT").Text = "100"
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "I'veInsertedtheCorrectUsernameHere"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "I'veInsertedtheCorrectPassHere"
session.findById("wnd[0]/usr/txtRSYST-LANGU").Text = "PT"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").setFocus
session.findById("wnd[0]/usr/pwdRSYST-BCODE").caretPosition = 10
session.findById("wnd[0]").sendVKey 0
Thanks for the help!
I am using the exact same script, which I found somewhere on the SAP help forums.
When I've encountered this issue before it's usually because the SAP GUI window was loaded AFTER lines
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "username"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "password"
There are two ways to fix this particular script. One is to add a MsgBox that will pause the script, but give SAP GUI enough time to load. The other is to add WScript.Sleep(<a few seconds>) to allow SAP GUI to load. Like so ...
Note that the below code has BOTH examples, but only 1 is necessary. I prefer the .Sleep() because it requires no external input from a user.
If IsObject(WSHShell) Then
' Removed for clarity
End If
MsgBox "Click OK to continue" ' <-- MsgBox to pause script
WScript.Sleep(5000) ' <--- Wait 5 seconds for SAP GUI to load
If Not IsObject(application) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(connection) Then
Set connection = application.Children(0)
End If
If Not IsObject(session) Then
Set session = connection.Children(0)
End If
If IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End If
session.findById("wnd[0]").resizeWorkingPane 164,40,false
session.findById("wnd[0]/usr/txtRSYST-BNAME").text = "username"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = "password"
session.findById("wnd[0]/usr/pwdRSYST-BCODE").setFocus
session.findById("wnd[0]/usr/pwdRSYST-BCODE").caretPosition = 14
session.findById("wnd[0]").sendVKey 0
And of course, storing username and password in plain text is not a good practice. However, obfuscating passwords with the VBScript InputBox() is not possible. You will have to use the command line, or create an IE object which is outside the scope of this question
Here's some VBS code that tries to wait for SAP to login and load properly. It worked well for me so far.
Function SAP_start_and_login(connection_string, use_sso, user, pass)
WScript.Echo "executing function SAP_start_and_login()"
REM Variables! Must declare before using because of Option Explicit
Dim WSHShell, SAPGUIPath
REM Main
Set WSHShell = WScript.CreateObject("WScript.Shell")
If IsObject(WSHShell) Then
REM Set the path to the SAP GUI directory
SAPGUIPath = "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\"
REM Starts the SAP GUI
if use_sso then
WSHShell.Exec SAPGUIPath & "sapshcut.exe -client={your_client} -sysname=whatevah -gui=" & connection_string & " -snc_name={your_snc_name} -snc_qop={your_snc_qop}"
else
WSHShell.Exec SAPGUIPath & "sapshcut.exe -client={your_client} -sysname=whatevah -gui=" & connection_string & " -user=" & user & " -pw=" & pass
end if
REM WSHShell.Exec SAPGUIPath & "saplogon.exe """ & system & """"
Set WSHShell = Nothing
WScript.Echo "{waiting for SAP to finish loading..}"
SAP_start_and_login = WaitForSAP(connection_string, 50)
WScript.Sleep 1000
End If
End Function
Function CheckSapIsRunning(connection_string)
Running = False
Ready = False
If Not IsObject(application) Then
On Error Resume Next
Set SapGuiAuto = GetObject("SAPGUI")
If (Err.Number <> 0) Then
WScript.Echo "SAPGUI object not found yet"
' Error raised, object not found.
' Restore normal error handling.
On Error GoTo 0
Else
'WScript.Echo "einai ok"
' Object found.
' Restore normal error handling.
On Error GoTo 0
Set application = SapGuiAuto.GetScriptingEngine
If application.Connections.Count() > 0 Then
For i = 0 To (application.Connections.Count()-1)
REM WScript.Echo i
Set Connection = application.Children(0+i)
Conn = Connection.ConnectionString()
REM WScript.Echo Conn
If InStr(Conn, connection_string) Then
Running = True
Exit For
End If
Next
End If
If Running Then
REM WScript.Echo connection_string + " is running!"
REM WScript.Echo "sessions="+CStr(connection.Children.Count)
If Not IsObject(session) Then
if connection.Children.Count > 0 then
Set session = connection.Children(0)
If IsObject(WScript) Then
WScript.ConnectObject session, "on"
WScript.ConnectObject application, "on"
End If
If not session.Busy then
Ready=True
REM WScript.Echo connection_string + " session is ready!"
Dim sapWindow
set sapWindow = session.findById("wnd[0]", False)
if sapWindow is Nothing then
WScript.Echo connection_string + " sap window element not there yet"
else
WScript.Echo connection_string + " is loaded and visible!"
end if
Else
WScript.Echo connection_string + " session is busy!"
end if
else
WScript.Echo connection_string + " session not loaded yet!"
end if
End If
else
WScript.Echo connection_string + " not running!"
End If
End If
End If
REM WScript.Echo application.Connections.Count()
CheckSapIsRunning = Ready
End Function
Function WaitForSAP(connection_string, timeout)
counter = 0
returnValue = False
While NOT CheckSapIsRunning(connection_string) AND counter < timeout
counter = counter + 1
WScript.Sleep 1000
REM WScript.Echo connection_string + " is not ready"
WEnd
if counter = timeout then
WScript.Echo "timeout of " + CStr(timeout) + " seconds reached."
else
returnValue = True
end if
WaitForSAP = returnValue
End Function
This can be used like this
If SAP_start_and_login(connection_string, use_sso, username, password) Then
If Not IsObject(application) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set application = SapGuiAuto.GetScriptingEngine
End If
...{the rest of your recorded script}
Else
WScript.Echo "Could not get a functioning SAP session"
WScript.Quit 1
End If
I'm using sapshcut.exe because it was easy to have both SSO and non SSO in a similar manner. The connection string is important in order to distinguish and identify the instance of SAP that you want to use in the rest of the script. It can be found from your current shortcut along with the SSO parameters that you might be using. If the SSO is true the user and pass parameters are not used. The timeout is also useful to avoid an endless loop if SAP is down or unreachable.
This solution does not need a static sleep in the script in order to wait for SAP to load which could prevent issues if SAP took more than expected to load. Also no time is wasted if it is loaded sooner than expected.
I am preparing vbscript to run bat files where bat file name contains version number, Script have to search for bat file with matching version name . Once Ran,The result Text file will be generated with same version number. I have to search for Text file with same version number and read the txt file for error or msg, if error found i want to display it.
I know my requirement is little too much.
But I am finding little difficulty in debugging the code.I am stuck.
Can any one help me to resolve the issue.
Thank You
here is my script,
I am passing values for sql query from excel sheet.
Dim Ver, Version_Number
Dim con
Dim rs
Set con=createobject("adodb.connection")
Set rs=Createobject("adodb.recordset")
Set PinXL = CreateObject("Excel.application")
Set PinWB = PinXL.Workbooks.Open("C:\maspects\Trial.xls") '// Login and Enable Debug Window in application
Set PinWS = PinWB.Worksheets("Sheet1")
varr = Cstr(PinWS.Cells(2,1).Value)
varr1 = trim(varr)
usename = Cstr(PinWS.Cells(2,2).Value)
UN = trim(usename)
password = Cstr(PinWS.Cells(2,3).Value)
PWD = trim(password)
IrisDB = Cstr(PinWS.Cells(2,4).Value)
DB = trim(IrisDB)
Site_Name = Cstr(PinWS.Cells(2,5).Value)
Site = trim(Site_Name)
con.open"provider=sqloledb.1;server=" & varr1 & ";uid=" & UN & ";pwd=" & PWD & ";database=" & DB &""
Wscript.sleep 1000*3
rs.Open "select * from tblSettingsUnique where [Setting Name] like '%Revision%'" ,con
Wscript.sleep 1000*2
Version_Number = rs.Fields("Setting Value")
Ver = Version_Number
msgbox Ver
Call Execute
PinWB.Save
PinWB.Close
PinXL.Quit
Wscript.Quit
Function Execute
If Ver < PinWS.Cells(2,6).Value = "True" Then ' if Ver is less than Cell(2,6) value then application should come out of loop
For i = Ver to PinWS.Cells(2,6).Value step 1
msgbox i
Set WShell = CreateObject("WScript.Shell")
For each f in Wshell.Getfolder("C:\maspects\DB_script").Files
BatFile = instr(f.File , "4_0_"&i )
WShell.Run ("CMD /K C:\maspects\DB_script\"&batFile &".bat" & Varr1 &" "& UN &" "& password )
Call msg
Next
Next
End If
End Function
Function msg
Set TxtObject = CreateObject("scripting.FileSystemObject")
For each ResFile in TxtObject.GetFolder("C:\maspects\DB_script").Files
TargetFile = InStr(ResFile.File , "4_0_"&i )
Set TxtFile = TxtObject.openTextFile("C:\maspects\DB_script\"&TargetFile, 1 ,true)
Do until TxtFile.AtEndOfStream
For each F in TxtFile.Readline
if InStr (F,"msg" ) = "True" and InStr (F,"msg 207" )= "False" Then
msgbox "Error in:"&TargetFile
React =Cint(Inputbox("Go through the Result file:"&TargetFile &"Enter '1' to Continue '0' to Quit"))
If React = "0" Then
TextObject.Close
Wscript.Quit
End if
End If
Next
Loop
TextObject.Close
Next
End Function
I have a script that I am currently using to check when that network goes up or down. Its writing to a pinglog.txt .
For the life of me I can not figure out how to get it to write to the event log when the network goes down. Where it says:
Call logme(Time & " - " & machine & " is not responding to ping, CALL FOR
HELP!!!!",strLogFile)
Thats what I need to write to the Event Log "Machine is not repsonding to ping, CALL FOR HELP!!!!
'Ping multiple computers and log when one doesn't respond.
'################### Configuration #######################
'Enter the IPs or machine names on the line below separated by a semicolon
strMachines = "4.2.2.2;8.8.8.8;8.8.4.4"
'Make sure that this log file exists, if not, the script will fail.
strLogFile = "c:\logs\pinglog.txt"
'################### End Configuration ###################
'The default application for .vbs is wscript. If you double-click on the script,
'this little routine will capture it, and run it in a command shell with cscript.
If Right(WScript.FullName,Len(WScript.FullName) - Len(WScript.Path)) <> "\cscript.exe" Then
Set objWMIService = GetObject("winmgmts: {impersonationLevel=impersonate}!\\.\root\cimv2")
Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")
objProcess.Create WScript.Path + "\cscript.exe """ + WScript.ScriptFullName + """", Null, objConfig, intProcessID
WScript.Quit
End If
Const ForAppending = 8
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strLogFile) Then
Set objFolder = objFSO.GetFile(strLogFile)
Else
Wscript.Echo "Log file does not exist. Please create " & strLogFile
WScript.Quit
End If
aMachines = Split(strMachines, ";")
Do While True
For Each machine In aMachines
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery("select * from Win32_PingStatus where address = '"_
& machine & "'")
For Each objStatus In objPing
If IsNull(objStatus.StatusCode) Or objStatus.StatusCode<>0 Then
Call logme(Time & " - " & machine & " is not responding to ping, CALL FOR
HELP!!!!",strLogFile)
Else
WScript.Echo(Time & " + " & machine & " is responding to ping, we are good")
End If
Next
Next
WScript.Sleep 5000
Loop
Sub logme(message,logfile)
Set objTextFile = objFSO.OpenTextFile(logfile, ForAppending, True)
objtextfile.WriteLine(message)
WScript.Echo(message)
objTextFile.Close
End Sub
Sorry about the spacing in the code. Thanks for the help
Use the WshShell object:
object.LogEvent(intType, strMessage [,strTarget])
object WshShell object.
intType Integer value representing the event type.
strMessage String value containing the log entry text.
strTarget Optional. String value indicating the name of the computer
system where the event log is stored (the default is the local
computer system). Applies to Windows NT/2000 only.
Like so:
Option Explicit
Dim shl
Set shl = CreateObject("WScript.Shell")
Call shl.LogEvent(1,"Some Error Message")
Set shl = Nothing
WScript.Quit
The first argument to LogEvent is an event type:
0 SUCCESS
1 ERROR
2 WARNING
4 INFORMATION
8 AUDIT_SUCCESS
16 AUDIT_FAILURE
EDIT: more detail
Replace your entire 'logme' sub-routine with this
Sub logme(t,m)
Dim shl
Set shl = CreateObject("WScript.Shell")
Call shl.LogEvent(t,m)
Set shl = Nothing
End Sub
Then change this line:
Call logme(Time & " - " & machine & " is not responding to ping, CALL FOR HELP!!!!",strLogFile)
To:
Call logme(1, machine & " is not responding to ping, CALL FOR HELP!!!!")
I have a VB Script that opens a spreadsheet, executes RefreshAll to update the sheet from external data, then does SaveAs a .CSV I had the script working as it should, then moved job to run on another computer. The job is running unattended through the Task Scheduler and now my error log shows ERROR 424 and the script no longer updates the spreadsheet, nor saves the .CSV. The script does run as it should on this machine interactively. The Job is using my credentials to run unattended. Anyone have any help on the Error 424???
Here is code snippet:
dim sLogFile, logFSO, objLogFile
sLogFile = "F:\Feed\FeedLog.log"
Set logFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = logFSO.OpenTextFile(sLogFile, 8, True)
Dim objExcel
Dim objWorkBook, objWorksheet
Set objExcel = CreateObject("EXCEL.APPLICATION")
Set objWorkBook = objExcel.Workbooks.Open("F:\Feed\FeedOlap.xlsx")
Set objWorksheet = objWorkbook.Worksheets("Sheet6")
objLogFile.WriteLine (" " & DATE & " " & TIME & " Starting Refresh")
objworkbook.Refreshall
IF ERR THEN
objLogFile.WriteLine "Error" & Err.Number
End If
objLogFile.WriteLine (" " & DATE & " " & TIME & " Refresh Complete")
objExcel.DisplayAlerts=FALSE
objWorkBook.Save
objWorksheet.SaveAs "F:\Feed\FeedOlapCSV.csv", 6
objWorkBook.Close True
objExcel.Quit
Set objWorkBook = Nothing
Set objExcel = Nothing
objLogFile.WriteLine (" " & DATE & " " & TIME & " CSV Created")
Seeing as how you are refreshing from external data, there must be a missing link to one of your external data files... You'd probably need to investigate every single external data link and make sure you can still get to it in your new location. (e.g. privileges to every location, mapped drives for your domain user, etc.)
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