VB piping STDOUT from cmd.exe output to to write to textbox - vb.net

I'm trying to adapt a VBscript that runs the QWINSTA command against a text file I've defined as an array and displays the results in a text file.
after looking at numerous examples on Stack and other sites this is my latest iteration, that displays everything except the STDOUT, which is really what I'm after, not sure if it's an issue with how I'm calling the command piping the output or what. I'm also passing two variables as arguments to complicate matters :)
The Text file that stdout is piped to is empty after the FOR Loop completes
I may be going the long way about this, most of my past experience with this is in BATCH
For Each server In RemotePC
'The Query is launched
Dim Query As New ProcessStartInfo
Query.WorkingDirectory = "c:\"
Query.Arguments = server & " " & profile & " >C:\Windows\Temp\SFOUT.txt"
Query.FileName = "QWINSTA"
Query.WindowStyle = ProcessWindowStyle.Hidden
Process.Start(Query)
'Call Shell("QWINSTA /SERVER:" & server & " " & profile & " >C:\Windows\Temp\SFOUT.txt", vbHidden, Timeout:=5000)
Dim SFOUT As New IO.StreamReader("C:\windows\temp\SFOUT.txt")
'Results are Echoed to TextboxResults
TextBoxResults.Text &= "__________________________________________________________" & ControlChars.CrLf
TextBoxResults.Text &= server & ControlChars.CrLf
TextBoxResults.Text &= SFOUT.ReadToEnd & ControlChars.CrLf
SFOUT.Close()
Next
Here is what the working code in VBscript looks like
For Each server In RemotePC
Dim WshShell, oExec
Set WshShell = CreateObject("WScript.Shell")
Set StrDir = "QWINSTA /SERVER:" & server & " " & profile
'The Query is launched
Set oExec = WshShell.Exec(StrDir)
'We wait for the end of process
Do While oExec.Status = 0
WScript.Sleep 500
Loop
'We scan and only display the command output of commands without NULL output
Do While oExec.StdOut.AtEndOfStream <> True
Results.WriteLine("__________________________________________________________")
Results.WriteLine(server)
Results.WriteLine oExec.StdOut.ReadLine
Loop
NEXT
Any help is appreciated
#Nilpo
this is what I get back
SESSIONNAME USERNAME ID STATE TYPE DEVICE
console Matt 1 Active
I've built something similar to this using QWINSTA and piping the output in batch and it works flawlessly, just having issues adapting this.
here's the last thing I tried I tried to simplify things by calling something as basic as notepad.exe, and even trying to define the environment variable thinking it's not reading %PATH%, in reply to #Nilpo
Dim Query As New Process
Query.StartInfo.FileName = "notepad.exe"
'Query.StartInfo.Arguments = server & " " & profile & " >C:\Windows\Temp\SFOUT.txt"
Query.StartInfo.UseShellExecute = False
Query.StartInfo.RedirectStandardOutput = True
Query.StartInfo.WindowStyle = ProcessWindowStyle.Normal
Environment.SetEnvironmentVariable("PATH", "%PATH%;" & "C:\Windows\System32\notepad.exe")
Query.Start()

You should have a space after the output redirection.
Query.Arguments = server & " " & profile & " >C:\Windows\Temp\SFOUT.txt"
Should be
Query.Arguments = server & " " & profile & " > C:\Windows\Temp\SFOUT.txt"
That being said, the only thing I can see that may not work is here.
Query.WorkingDirectory = "c:\"
Query.Arguments = server & " " & profile & " >C:\Windows\Temp\SFOUT.txt"
Query.FileName = "QWINSTA"
Query.WindowStyle = ProcessWindowStyle.Hidden
Process.Start(Query)
I'm not sure that you can use arguments in this fashion. Your output redirection is being read as a literal argument when it's really not. In a command line environment it's interpreted as a separate command, not an argument to the first command. It's very similar to piping in that manner. Supplying this as an argument in your code probably won't work as expected. You may want to go back to the Call Shell method. That will execute the command as if it were on the command line.
[Edit]
I was correct. Here is the proper way to do this using your method.
Query.WorkingDirectory = "c:\"
Query.Arguments = server & " " & profile & " >C:\Windows\Temp\SFOUT.txt"
Query.FileName = "QWINSTA"
Query.WindowStyle = ProcessWindowStyle.Hidden
'Redirect output
Query.UseShellExecute = False
Query.RedirectStandardOutput = True
Process.Start(Query)
'Read the output
Dim output As String = Process.StandardOutput.ReadToEnd
' wait for the process to terminate
Process.WaitForExit

Related

How can I see the results and how can the windows Close

I have this code, and I´m calling one Java program to pass the aurguments, that I select in VB.
My issues is:
The cmd windows open, but I can't see what the program is doing, I only see on the window the arguments that are pass, and when finish, the window don't close.
enter image description here
and when program stop, the windows don't close.
enter image description here
This is the result if I run by command line
enter image description here
txbSendCommand.Text = "java -jar FACTEMICLI-2.5.16-33194-cmdClient.jar " & "-i " & TextBox1.Text & "" & " -n " & stNIF & " -p " & stPassword & " -a " & iAno & " -m " & iMes & " -op " & stvalidar & stFicheiroEscolhido & " -o c:\saft\outputfile.xml"
Dim stcaminhoexterno As String
If stErrorMessage = False Then
Dim app As New ProcessStartInfo("cmd.exe") With {.RedirectStandardInput = True, .UseShellExecute = False, .CreateNoWindow = False}
Dim myProcess As New Process
myProcess = Process.Start(app)
Dim arguments As String = txbSendCommand.Text
myProcess.StandardInput.WriteLine(arguments)
myProcess.Close()
End If
How can I see the results in the external windows, or better even in a windows or something that I can have in the form.
How Can the window close after the process is done

Access VBA Export to New CSV Run-time Error 3011

I have code that exports a dynamic query to a csv. First I save the sql to an existing query, updating it's sql. Then I use that as the query defs, provide saved specs, and want to export to a dynamically constructed csv file name. The csv doesn't exist yet, so I am creating it. I thought doing a docmd.transfertext acExportDelim would create the file.
I end up getting the following error:
Run-time error '3011':
The Microsoft Access database engine could not find the object 'filename.csv'.
Make sure it is spelled correctly. If 'filename.csv' is not a local object,
check your network connection or contact the server administrator.
The "filename.csv" in the error, is exactly what I construct in the below code, and the name of the csv file I want to be created by this process.
Private Sub cmdExportList_Click()
Dim fsql As String
Dim f As Form
Dim RS As DAO.Recordset
Dim MyDate As String
Dim args As String
Set f = Forms!frmMyLists.Form.frmMyLists_SubResults.Form
args = Nz(Forms!frmMyLists.Form.cboMyList.Value, "00")
fsql = "SELECT * " & _
"FROM tblVFileImport "
fsql = fsql & "WHERE tblVFileImport.ListName = '" & args & "' "
fsql = fsql & "ORDER BY tblVFileImport.ID"
CurrentDb.QueryDefs("qryListExportSpecs").SQL = fsql
MyDate = Format(Now(), "yyyymmdd")
If IsDev = True Then
vFile = "C:\LocalPath\VFileData\ExportList\" & args & MyDate & ".csv"
Else
vFile = "\\Server\Share\ExportList\" & args & MyDate & ".csv"
End If
DoCmd.TransferText acExportDelim, "MyListExportSpecs", "qryListExportSpecs", vFile, True
Application.FollowHyperlink vFile
MsgBox "All Set! " & args & " tagged list is now open in Excel. Have Fun!", vbOKOnly, "Export Complete"
End Sub
Right now, I am in my dev copy (IsDev = True) so I'm just going to that local path. I tried creating a csv with the name first, but if I don't write anything to it (which I don't want to, because I'm wanting to transfer the text to it) then it goes away when I close it. I am wondering if it does that because it's 0 bytes. Does anyone know what I am doing wrong? Thanks!
Edit:
I found that if I tested by creating the csv before running the code, so it would already exist, the code was deleting it. I researched that and found the export specs can sometimes mess things up. I removed the export specs and now it works!
So this is :
DoCmd.TransferText acExportDelim, "", "qryListExportSpecs", vFile, True

How to use multiple commands with path references in command prompt

I'm new to this forum, so please correct me if I'm asking this the wrong way or not specific enough..
While coding in VB.NET I'm trying to pass multiple commands, and an argument containing a reference to a path:
Dim p As New Process
Dim pi As New ProcessStartInfo
pi.Arguments = " " & "/K """ & "C:\program files\gdal\gdalshell.bat" & """ & " & "cd C:\program files\gdal" & _
" & " + "gdal_translate" + " -of Jpeg -outsize 2000 2000 """ & "D:\box sync\my box (907070)\RIS_RHDHV_Overgang\GDAL\test2.xml" & """ "
pi.FileName = "C:\windows\syswow64\cmd.exe"
p.StartInfo = pi
p.Start()
The command prompt returns:
'C:\Program' is not recognized as an internal or external command, operable program or batch file.
I did some research on the matter and found:
vb.net How to pass a string with spaces to the command line
This however still doesn't seem to solve the problem. When I execute the following code, it runs without issues:
Dim p As New Process
Dim pi As New ProcessStartInfo
pi.Arguments = " " & "/K """ & "C:\program files\gdal\gdalshell.bat" & """ & " & "cd C:\program files\gdal" & _
" & " + "gdal_translate"
pi.FileName = "C:\windows\syswow64\cmd.exe"
p.StartInfo = pi
p.Start()
To me it looks like the problem is caused by the path reference inside an argument. I have read and used the different answers for using multiple commands, without any luck.
It would be great if someone could help me on this topic.
Kind regards,
Stuart
First of all, as a little note you don't need to add a space in the beginning of the arguments. That's only done when you write the entire command (including the executable) in one line.
Now, the correct way to pass a path as an argument is to surround it with quotes. So something like this should do:
(please note that I have also shortened some unnecessary concatenations, etc.)
pi.Arguments = "/K """"C:\program files\gdal\gdalshell.bat"" & cd ""C:\program files\gdal"" & " & _
"gdal_translate -of Jpeg -outsize 2000 2000 ""D:\box sync\my box (907070)\RIS_RHDHV_Overgang\GDAL\test2.xml"""""
EDIT:
I found that you also have to put the entire text after /K in quotes for it to work.

Using the process object with multiple arguments

I have a piece of code that calls MSTEST with multiple arguments defining a specific set of tests to run and an environment to run it in. Currently the code looks like this (a bit messy but it works):
Process.Start(Environment.GetEnvironmentVariable("VS110COMNTOOLS")
& "..\Ide\MSTEST.EXE", "/Testsettings:""" & rwSettings & """"
& " /Testcontainer:""" & rwContainer & """" & " /Resultsfile:"""
& rwResults & """")
With the various variables defined previously. I had to use the GetEnvironmentVariable("VS110COMNTOOLS") call because I can't guarantee an install location for Visual Studio and need access to the MSTEST executable. "..\Ide\MSTEST.EXE" is because the environment variable will only get me to the right area and I'll need to have the system navigate to IDE before it finds MSTEST.
I want to clean this up because it's not very elegant or readable, and also because I want to be able to raise events running this process. However, I'm not seeing documentation on how the Process class handles arguments. How can I have the Process object I create handle the multiple arguments (that might have spaces in the name)?
You may try this:
Dim Testsettings As String = "/Testsettings:"""
Dim Testcontainer As String = " /Testcontainer:"""
Dim Resultsfile As String = " /Resultsfile:"""
Dim Quote As String = """"
Dim p As New Process()
p.StartInfo.FileName = Environment.GetEnvironmentVariable("VS110COMNTOOLS")
& "..\Ide\MSTEST.EXE"
p.StartInfo.Arguments = Testsettings & rwSettings & Quote & Testcontainer
& rwContainer & Quote & Resultsfile & rwResults & Quote
p.Start()

Arguments from Visual Basic to Batch File

I know this is easy. I am an administrator, not a FT programmer. I am trying to pass the prjFilename and emailFilename arguments to a Batch file. To ensure the values are correct, I am popping a MsgBox in the Else branch. Everything is fine there. The problem is that when I attempt to use the variable in the Batch file, that variable string is cut off at the very first space in the filename path.
So when I echo %1% to test it, I get a truncated path. Any help is appreciated.
If prjFilename = "" Then
MsgBox("Please select a GSA Project File to process")
ElseIf emailFilename = "" Then
MsgBox("Please select a list of emails to process")
Else
Dim DosRun As Process = New Process
Dim strArgs As String
MsgBox(prjFilename)
MsgBox(emailFilename)
strArgs = prjFilename & " " & emailFilename
MsgBox(strArgs)
DosRun.StartInfo.WindowStyle = ProcessWindowStyle.Maximized
DosRun.StartInfo.FileName = "C:\Users\Eric\Desktop\KRUSH\krush.cmd"
DosRun.StartInfo.Arguments = prjFilename & " " & emailFilename
DosRun.Start()
If either of prjFilename or emailFilename contain spaces, then you need to place double quotation characters around them when passing them to the batch file. A double quotation character literal in VBA is """" (I kid you not).
strArgs = """" & prjFilename & """" & " " & """" & emailFilename & """"
I normally define Public Const vbQuote as String = """" at the top of a module and use that.