Keep console window open after completion - batch-file

I'm running a bat file and having the output displayed in the console window. Right now, I am having the bat file intentionally fail (bat file contains "STARET www.webaddress.com"). The error catching and everything works, but the console window closes immediately. I would like to keep it open, but so far my searching how to do so hasn't come up with any solutions.
The code I currently have:
Me.processStartInfo = New ProcessStartInfo("C:\Admin\PsTools\psexec.exe", "\\PCName -u domain\" & user & " -p " & pass & " pathtobatfile")
Me.processStartInfo.RedirectStandardError = True
Me.processStartInfo.RedirectStandardOutput = True
Me.processStartInfo.WindowStyle = ProcessWindowStyle.Hidden
Me.processStartInfo.UseShellExecute = False
Dim process As System.Diagnostics.Process = Nothing
'Start the process, which runs the bat file on the remote server
process = System.Diagnostics.Process.Start(Me.processStartInfo)
AddHandler process.OutputDataReceived, AddressOf OutputHandler
process.BeginOutputReadLine()
process.WaitForExit()
Dim errorresponse As DialogResult
If process.HasExited And process.ExitCode <> 0 Then
errorresponse = MessageBox.Show("There was an error. Exit code: " & process.ExitCode & _
". Do you wish to view the log?", "Error", MessageBoxButtons.YesNo, MessageBoxIcon.Error)
ElseIf process.HasExited And process.ExitCode = 0 Then
MessageBox.Show("The update completed successfully.", "Success", MessageBoxButtons.OK)
End If
If errorresponse = DialogResult.Yes Then
'To fill in later
End If
And the event handler sub:
Private Shared Sub OutputHandler(ByVal sendingProcess As Object, ByVal output As DataReceivedEventArgs)
Console.WriteLine(output.Data)
End Sub
I've also tried just doing synchronous output (using StreamReader and Console.Writeline with a Readline()), but that didn't work either.

Try to add at the end
set err=%ERRORLEVEL%
pause
exit %err%

Try adding pause at the end of the BAT file. Alternatively, if you're lauching the bat file via a cmd process, you can add the /k argument.
cmd /k pathToBatFile

Related

How to Redirect output of cmd command "adb logcat" in Visual Studio(in cmd it never stops unless u press Ctrl+ PauseBreak)?

I am using Visual Studio to generate the adb logcat through command prompt and put it into a text box. The thing is that the output of the logcat keeps generating due to which the program gets stuck.
This is my Start logging button code.
Dim procForLog As ProcessStartInfo = New ProcessStartInfo("cmd.exe")
Dim prForLog As Process
procForLog.CreateNoWindow = True
procForLog.UseShellExecute = False
procForLog.RedirectStandardInput = True
procForLog.RedirectStandardOutput = True
prForLog = Process.Start(procForLog)
prForLog.StandardInput.WriteLine("adb logcat")
prForLog.StandardInput.Close()
While log = True
Dim logLineReader As String = prForLog.StandardOutput.ReadLine()
TextBox1.Text += logLineReader + vbNewLine
End While
prForLog.StandardOutput.Close()
'log' is a public boolean variable. I control 'log' value through another button called "stop logging button".
This is my stop logging button code
log = false
How to I output a log that never ends unless you tel it to?
Like if I type the same command in command prompt "adb logcat" it keeps generating output until I press Ctrl+PauseBreak.
Change
prForLog.StandardInput.WriteLine("adb logcat")
To
prForLog.StandardInput.WriteLine("adb logcat -d")

Adding some kind of event listener for network connectivity

I have at my disposal the following resources:
VBScript, WMI Queries, Registry Key/Values, .bat batch files
Using any combination of these resources I need to create some kind of event listener that will trigger a .bat file when the computer re-establishes connection with a network.
I work in lab that constantly has machines changing networks and we are using BGinfo.exe to show what network the computer is on in the background image. So what I am trying to do is set up a listener that checks if the network loses connection and re-connects, then re-run the batch file to update the background.
How can I do something like eventListener.on('connection', goIntoSomeCallbackFunction)? If this is not possible using VBscript then is there an alternative?
Here is my solution:
dim shell, ip
set shell=createobject("wscript.shell")
function main()
Dim status, result
result = False
'Here we have to loop every few seconds to look at connectivity
Do
result = statusChanged()
If result Then
shell.Run "D:\tools\Batches\updateBG.bat"
End If
WScript.Sleep(1000)
Loop While True
End function
function statusChanged()
Dim found, status
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration")
status = False
found = False
For Each result in colItems
If Not isNull(result.IPAddress) Then
If ip <> result.IPAddress(0) Then
ip = result.IPAddress(0)
status = True
End If
End If
Next
statusChanged = status
End function
main()

VB.net GetProcess Options

I currently have the following code that runs an external Virtual Application(created with Cameyo), when the Run Button is clicked. I also have a Timer that checks ever second to see if the Process(virtual exe program) is still open. In theory the GetProcessByName should find the program listed in the Task Manager right? However it doesn't! I even tried using GetProcessByName to Kill the process (one another button clicked), but the processs is not killed.
Could it be because I virtualized the program that I want GetProcessByName to recognize? Therefore the name of the Task in the Task Manager is not correct?.
Example
The program started: SmartDefrag.virtual.exe
It runs
The Task Manager shows it as SmartDefrag.exe
Use GetProcessByName("SmartDefrag.exe") to Disable Run Button if process SmartDefrag.exe running.
Does not Disable Run Button.
Could I use TITLE OF PROCESS? Or will the PID be the same everytime the process opens? Any other options?
Code:
Private Sub SMDFRunAppMainButton_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles SMDFRunAppMainButton.Click
' LoadingSMDFMainButton.Visibility = Windows.Visibility.Visible
Dim downloadlocation As String = (currentpath & "\1stAidApps\SMDF\SmartDefrag.virtual.exe")
My.Settings.FileLoad = downloadlocation
Try 'Errors on Cancel
dp1Timer = New DispatcherTimer
dp1Timer.Interval = TimeSpan.FromMilliseconds(1000)
AddHandler dp1Timer.Tick, AddressOf TickMe1
dp1Timer.Start()
fileload = My.Settings.FileLoad
Process.Start(fileload)
Catch ex As Exception
MessageBox.Show("Failed to launch. Please try again.", "Launch Failed")
End Try
End Sub
Private Sub TickMe1()
Dim p() As Process
p = Process.GetProcessesByName("SmartDefrag.exe")
If p.Count > 0 Then
LoadingSMDFMainButton.Visibility = Windows.Visibility.Hidden
SMDFRunAppMainButton.IsEnabled = False
Else
SMDFRunAppMainButton.IsEnabled = True
End If
End Sub
GetProcessByName doesn't take the full path, but rather the "name" of the process. This will likely need to be GetProcessByName("SmartDefrag").
From the documentation for GetProcessByName:
The process name is a friendly name for the process, such as Outlook, that does not include the .exe extension or the path.

Cannot connect project to a SQL Server database

I have a problem while trying to copy my project folder to another hard drive. My project in Visual Studio is defined in h:\ and while run exe file project no any problem but while copy folder project to another hard drive I have a problem to connect the application to SQL Server.
See these screenshots:
http://upload.tehran98.com/img1/f9kio8ssjofg1lhkjdg.jpg
http://upload.tehran98.com/img1/k6ajdb22xhdjrgcn419.jpg
For example in login form and in login button my code is:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim conn As New SqlConnection("Server=.\SQLExpress;AttachDbFilename=" + Environment.CurrentDirectory + "\Database\Automation.mdf;Database=Automation;Trusted_Connection=Yes;")
s2 = "Select count( * ) from Login where UserName = '" & TextBox1.Text & "' and Password = '" & TextBox2.Text & "'"
Dim com As New SqlCommand(s2, conn)
Dim res As Object
conn.Open()
res = com.ExecuteScalar()
conn.Close()
If res = 1 Then
MsgBox("Welcome Dear " + TextBox1.Text, MsgBoxStyle.OkOnly, "Login Successful")
us = TextBox1.Text
If us = "admin" Then
Main.Label4.Text = "ADMINISTRATOR"
Else
Main.Label4.Text = "USER"
us = TextBox1.Text
Main.Button3.Enabled = False
Main.Button5.Enabled = False
Main.Button9.Enabled = False
End If
Main.Show()
Me.Hide()
Else
MsgBox("Invalid User OR Password", MsgBoxStyle.Critical, "Attention Please")
TextBox1.Text = ""
TextBox2.Text = ""
Exit Sub
End If
End Sub
You need to specify where the database is, you can't use Environment.CurrentDirectory. CurrentDirectory uses the path of the current working directory. So either move the database to the same hard drive or change the path to your database.
http://msdn.microsoft.com/en-us/library/system.environment.currentdirectory.aspx

Why does my winsock control not function correctly in vb6 within the context of a Form_QueryUnload?

My goal is to have this program send a logout command when the user is logging off or shutting down their pc.
The program is connected to a server application via a tcp socket using a Winsock object. Calling singleSock.SendData "quit" & vbCrLf is simply a way of logging out. I am going to start capturing data with Wireshark, but I'd like to know if I'm trying to do something fundamentally wrong.
Oddly enough, if I set Cancel to True, and allow a timer I have running to do the logout command, then call another unload, it works, however in testing this configuration (different code), this prevents the user from logging out the first time. They have to initiate a logout, it doesn't do anything, then they logout again and my program is gone at that point. Also oddly enough, in Vista the logout goes through after briefly displaying a screen saying my program was preventing the logout. Most of my deployment is on XP, which has the two logouts problem.
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
If UnloadMode = vbFormControlMenu Then
Me.WindowState = vbMinimized
Cancel = True
Else
If SHUTDOWN_FLAG = True Then
Cancel = False
Else
Cancel = True
SHUTDOWN_FLAG = True
End If
tmrSocket.Enabled = False
SHUTDOWN_FLAG = True
Sleep (1000)
singleSock.SendData "quit" & vbCrLf
Call pUnSubClass
'If singleSock.state <> sckConnected Then
' singleSock.Close
' tmrSocket.Enabled = False
' LogThis "tmrSocket turned off"
'End If
DoEvents
End If
End Sub
You're not waiting for the Winsock control to actually send the "quit" message. The SendData method is asynchronous: it can return before the data has actually been sent across the network. The data is buffered locally on your machine and sent at some later time by the network driver.
In your case, you are trying to send the "quit" message and then closing the socket almost immediately afterwards. Because SendData is asynchronous, the call might return before the "quit" message has actually been sent to the server, and therefore the code might close the socket before it has a chance to send the message.
It works when you cancel the unloading of the form first and let the timer send the "quit" message because you're giving the socket enough extra time to send the message to the server before the socket is closed. However, I wouldn't count on this always working; it's a coincidence that the extra steps gave the socket enough time to send the message, and it's not guaranteed to always work out that way.
You can fix the problem by waiting for the socket to raise a SendCompleted event after you send the "quit" message and before you close the socket. Below is a basic example. Note that the QueryUnload code is much simpler.
Private m_bSendCompleted As Boolean
Private m_bSocketError As Boolean
Private Sub singleSock_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
'Set error flag so we know if a SendData call failed because of an error'
'A more robust event handler could also store the error information so that'
'it can be properly logged elsewhere'
m_bSocketError = True
End Sub
Private Sub singleSock_SendCompleted()
'Set send completed flag so we know when all our data has been sent to the server'
m_bSendCompleted = True
End Sub
'Helper routine. Use this to send data to the server'
'when you need to make sure that the client sends all the data.'
'It will wait until all the data is sent, or until an error'
'occurs (timeout, connection reset, etc.).'
Private Sub SendMessageAndWait(ByVal sMessage As String)
m_bSendCompleted = False
singleSock.SendData sMessage
singleSock.SendData sMessage
Do Until m_bSendCompleted or m_bSocketError
DoEvents
Loop
If m_bSocketError Then
Err.Raise vbObjectError+1024,,"Socket error. Message may not have been sent."
End If
End Sub
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
'This is (almost) all the code needed to properly send the quit message'
'and ensure that it is sent before the socket is closed. The only thing'
'missing is some error-handling (because SendMessageAndWait could raise an error).'
If UnloadMode = vbFormControlMenu Then
Me.WindowState = vbMinimized
Cancel = True
Else
SendMessageAndWait "quit" & vbCrLf
singleSock.Close
End If
End Sub
You can make the code cleaner by putting the logic to send a message and wait for it to be sent in a separate class. This keeps the private variables and the event handlers in one place, instead of having them litter your main code. It also makes it easier to re-use the code when you have multiple sockets. I called the class SynchronousMessageSender for lack of a better name. This example also has more complete error handling:
SynchronousMessageSender.cls
Private WithEvents m_Socket As Winsock
Private m_bAttached As Boolean
Private m_bSendCompleted As Boolean
Private m_bSocketError As Boolean
Private Type SocketError
Number As Integer
Description As String
Source As String
HelpFile As String
HelpContext As Long
End Type
Private m_LastSocketError As SocketError
'Call this method first to attach the SynchronousMessageSender to a socket'
Public Sub AttachSocket(ByVal socket As Winsock)
If m_bAttached Then
Err.Raise 5,,"A socket is already associated with this SynchronousMessageSender instance."
End If
If socket Is Nothing Then
Err.Raise 5,,"Argument error. 'socket' cannot be Nothing."
End If
Set m_Socket = socket
End Sub
Private Sub socket_SendCompleted()
m_bSendCompleted = True
End Sub
Private Sub socket_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
m_bSocketError = True
'Store error information for later use'
'Another option would be to create an Error event for this class'
'and re-raise it here.'
With m_lastSocketError
.Number = Number
.Description = Description
.Source = Source
.HelpFile = HelpFile
.HelpContext = HelpContext
End With
End Sub
'Sends the text in sMessage and does not return'
'until the data is sent or a socket error occurs.'
'If a socket error occurs, this routine will re-raise'
'the error back to the caller.'
Public Sub SendMessage(ByVal sMessage As String)
If Not m_bAttached Then
Err.Raise 5,,"No socket is associated with this SynchronousMessageSender. Call Attach method first."
End If
m_bSendCompleted = False
m_bSocketError = False
m_socket.SendData sMessage & vbCrLf
'Wait until the message is sent or an error occurs'
Do Until m_bSendCompleted Or m_bSocketError
DoEvents
Loop
If m_bSocketError Then
RaiseLastSocketError
End If
End Sub
Private Sub RaiseLastSocketError()
Err.Raise m_lastSocketError.Number, _
m_lastSocketError.Source, _
m_lastSocketError.Description, _
m_lastSocketError.HelpFile, _
m_lastSocketError.HelpContext
End Sub
Example Use
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim sender As New SynchronousMessageSender
'Ignore errors since the application is closing...'
On Error Resume Next
If UnloadMode = vbFormControlMenu Then
Me.WindowState = vbMinimized
Cancel = True
Else
Set sender = New SynchronousMessageSender
sender.AttachSocket singleSock
sender.SendMessage "quit"
singleSock.Close
End If
End Sub
By using a separate class, now all the necessary code can be placed in the Form_QueryUnload, which keeps things tidier.
Wouldn't is be easier to just go without the QUIT command. In your server code just assume that the closing of a socket does the same thing as receiving a quit.
I addition, one thing you want to watch out for is abrupt shut downs of the client software. For example, a machine that losses power or network connection or a machine that goes into sleep or hibernate mode.
In those cases you should be periodically checking the connection for all of the clients from the server and closing any connections that do not respond to some kind of ping command.

Resources