Remote Process Execution in vb.net

P

Patrick A.

Dll written in VB.NET 2003 to start a command remotely.

You can :
- launch the command and wait until it's finished. (Ex. 1)
- launch the command providing a timeout in seconds, it will wait until
it's finished. If the command didn't terminate within the timeout, the
command is killed. (Ex. 2)
- launch the command and continue your processing after the command has
been started remotely (Ex. 3).

*******************************
* Example code To use the dll *
*******************************

Dim RE As New remoteExec.remoteExec

MsgBox("0")
Try
RE.Execute("c:\windows\notepad.exe", "remoteSrv") 'Ex. 1 : wait
until the process is finished
Catch ex As Exception
MsgBox(ex.Message())
End Try
MsgBox("end 0")

MsgBox("10")
Try
RE.Execute("c:\windows\notepad.exe", "remoteSrv", 10) 'Ex. 2 :
timeout of 10 seconds
Catch ex As Exception
MsgBox(ex.Message())
End Try
MsgBox("end 10")

MsgBox("-1")
Try
RE.Execute("c:\windows\notepad.exe", "remoteSrv", -1) 'Ex. 3 :
starts the command, don't wait until it's finished
Catch ex As Exception
MsgBox(ex.Message())
End Try
MsgBox("end -1")

**********************
* Dll code in VB.NET *
**********************

Imports System
Imports System.Management

Public Class remoteExec

' We use the pids ArrayList to keep track of which processes have
ended
' on the remote machine.
Private Shared pids As ArrayList = New ArrayList

' Execute a certain command on a remote machine without
' waiting for it to finish.
Public Overloads Shared Sub Execute(ByVal cmd As String, ByVal
machine As String)
Execute(cmd, machine, 0)
' Passing 0 is useful for running things like "md c:\foo",
which end too quickly and for the Win32_Processtermination event to be
caught
End Sub

' Execute a certain command on a remote machine, and wait
' a certain amount of time for it to finish. Do not use this method
if your command line may
' finish to fast (e.g. "md c:\mydir") because the process_end event
won't fire.
Public Overloads Shared Sub Execute(ByVal cmd As String, ByVal
machine As String, ByVal timeoutSeconds As Integer)
'Dim wait As Boolean = (timeoutSeconds > 0)
ManagementPath.DefaultPath = New
ManagementPath(String.Format("\\{0}\root\CIMV2", machine))
Dim procStart As ManagementClass = New
ManagementClass("Win32_ProcessStartup")
Dim ps As ManagementObject = procStart.CreateInstance
ps("ShowWindow") = 1
Dim procClass As ManagementClass = New
ManagementClass("Win32_Process")
SetOptions(procClass)
Dim watcher As ManagementEventWatcher = New
ManagementEventWatcher("select * from __instancedeletionevent WITHIN
0.1 where Targetinstance ISA 'Win32_Process'")
AddHandler watcher.EventArrived, AddressOf ProcessEnd
pids.Clear()
watcher.Start()
Try
Dim p() As Object = New Object() {cmd, Nothing, ps,
Nothing}
procClass.InvokeMethod("Create", p)
Dim pid As Integer = Convert.ToInt32(p(3))
' We'll wait until the process created no longer exists on
the remote
' machine
If timeoutSeconds > 0 Then

Dim endTime As DateTime =
DateTime.Now.AddSeconds(timeoutSeconds)

While ((DateTime.Compare(DateTime.Now, endTime) < 0) _
AndAlso Not pids.Contains(pid))
System.Threading.Thread.Sleep(1000)

End While
If Not pids.Contains(pid) Then
'Kill the process
Dim myManagementObjectSearcher As New
ManagementObjectSearcher("Select * from Win32_Process Where ProcessID =
" + Convert.ToString(pid))
Dim myManagementObjectCollection =
myManagementObjectSearcher.Get
Dim observer As ManagementOperationObserver = New
ManagementOperationObserver
For Each myManagementObject As ManagementObject In
myManagementObjectCollection
myManagementObject.InvokeMethod(observer,
"Terminate", Nothing)
Next

Throw New ApplicationException("Process timed out -
killed PID = " + pid.ToString)
End If
ElseIf timeoutSeconds = 0 Then
' Wait until the command finish on the remote server

While Not pids.Contains(pid)
System.Threading.Thread.Sleep(1000)
End While
Else
' The command has been started. Wait 500 milliseconds
and leave the command running without control
System.Threading.Thread.Sleep(500)
End If
Finally
watcher.Stop()
End Try
End Sub

' The event handler for the Process_End WMI event
Private Shared Sub ProcessEnd(ByVal sender As Object, ByVal e As
EventArrivedEventArgs)
Dim pid As Object =
CType(e.NewEvent.Properties("TargetInstance").Value,
ManagementBaseObject).Properties("Handle").Value
pids.Add(Convert.ToInt32(pid))
End Sub

' Set the authentication/impersonation options this
ManagementObject will use.
Private Shared Sub SetOptions(ByVal mo As ManagementObject)
mo.Scope.Options.Authentication = AuthenticationLevel.Default
mo.Scope.Options.Impersonation = ImpersonationLevel.Impersonate
mo.Scope.Options.EnablePrivileges = True
End Sub
End Class


*************************
* Based on this C# code *
*************************
http://groups.google.fr/group/micro...+event+won't+fire&hl=fr&#doc_0b5247d6a94159e3
(Carlos Garcia Jurado Suarez [MSFT])

http://www.expresscomputeronline.com/20040112/techspace02.shtml
(Yashavant Kanetkar)



Patrick.
 
Joined
Nov 6, 2009
Messages
2
Reaction score
0
Works for 2K server but not for a 2003 server

Is there some other setting that needs to be set?
 
Joined
Nov 6, 2009
Messages
2
Reaction score
0
Also is there something better in the lastest .net offerring to launch processes? Thanks, Rick
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top