Question USE WMI in VB 2008 to manage vnc server

mla_ca520

Member
Joined
Jul 30, 2009
Messages
8
Location
New Mexico
Programming Experience
Beginner
I have written the following script in VBS to check remote machines for VNC service running and to turn it on if it is not (pending user prompt) or to turn it off if it is on (same prompt). I have attempted to convert this to VB 2008. I have modified programs from the Microsoft code samples package to check for running services on my machine or on remote machines but can't figure out how to actually stop a service and then how to kill the process if the service won't shut down. Any help would be greatly appreciated. thanks,
Mike

(I added the VB 2008 code below this VBS)
when I try to kill a service on my machine, I get a Win32 Exception was unhandled - Access is denied - Error Code: -2147467259
----------
When I try to kill a service on a remote computer, nothing happens

----begin VBS below--------
'THIS SCRIPT WILL CHECK THE STATUS OF THE VNC SERVICE AND/OR PROCESS
'IT WILL PROMPT USER TO ALTER THE STATE OF THE SERVICE WITH YES OR NO PROMPT
'JULY 21, 2009 - to modify script change the following variables:
'strComputer, strProcess and strService - version 2.0
'---------------------------------------------------------------------------

'strComputer variable is assigned by user input of IP Addr or computer name
Dim strComputer : strComputer = InputBox ("Please Enter Client's IP Address", _
"Client IP Address", vbNullString)
Dim strProcess : strProcess = "'winvnc4.exe'"
Dim strService : strService = "'WinVNC4'"
Dim objWMIService, colProcesses, objShare
Dim objOutParams, colItems, YesOrNo, objProcess
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE Name = " & strProcess & "")
Set objShare = objWMIService.Get _
("Win32_Service.Name=" & strService & "")
'---------------------------------------------------------------------------
Function IsProcessRunning() 'Function to Test if VNC Process is Started
IsProcessRunning = False 'set default to false
If colProcesses.Count = 0 Then 'check to see if Process is started
IsProcessRunning = False 'process is not started function is false
Else
IsProcessRunning = True 'process started, set function to True
End If
End Function
'---------------------------------------------------------------------------
Function Service_State() 'Function to Test if VNC Service is Running
Service_State = False 'set default to false
Set objOutParams = objWMIService.ExecMethod _
("Win32_Service.Name=" & strService &"", "InterrogateService")
If objOutParams.ReturnValue = 0 then
Service_State = True 'service is running, set function to true
else
Service_State = False ' service not running, function is false
End If
End Function

'___________________________________________________________________________
'Begin Main Body of Script - above are declarations
'***************************************************************************
If Service_State = True then
'Service is running, msge box askes user if service should be stopped
YesOrNo = MsgBox(strComputer & " - " & strService & " is running" & _
Chr(13) & Chr(13) & "Press ""Yes"" to Stop VNC service" & _
Chr(13) & Chr(13) & "Press ""No"" to Exit", 4, "Attn: STOP " & _
strService & "?")
'if user clicks yes service will be stopped otherwise script exits
If YesOrNo = 6 then
'Stop_Sercie is subroutine below
Stop_Service
'pause 1.5 seconds to confirm process is stopped
Wscript.sleep 1500
'confirm that process is ended if not, kill process
If IsProcessrunning = True then
Kill_Process
End If
Else
'user clicked no, script exits and variables reset
Script_Exit
End If
else
'Service is not running, msge box asks user if service should be started
YesOrNo = MsgBox(strComputer & " - " & strService & " is NOT running" & _
Chr(13) & Chr(13) & "Press ""Yes"" to Start VNC service" & _
Chr(13) & Chr(13) & "Press ""No"" to Exit", 4, "Attn: START " & _
strService & "?")
'if user clicks yes, the service is started via subroutine
If YesOrNo = 6 then
'subroutine below to start service
Start_Service
Else
'user clicks no, script exits and variables are reset
Script_Exit
End If
End If
Script_Exit 'run subrouting to clear variables and exit script
'___________________________________________________________________________
'End Main Body of Script - below are subroutines
'***************************************************************************

Sub Kill_Process() 'Kill VNC Process
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery _
("SELECT * FROM Win32_Process WHERE Name = " & strProcess & "")
For Each objProcess in colProcesses
objProcess.Terminate()
Next
End Sub
'---------------------------------------------------------------------------

Sub Start_Service() 'Starts the VNC Service
Set objOutParams = objWMIService.ExecMethod _
("Win32_Service.Name="& strService & "", "StartService")
End Sub
'---------------------------------------------------------------------------

Sub Stop_Service() 'Stops the VNC Service
Set objOutParams = objWMIService.ExecMethod _
("Win32_Service.Name=" & strService & "", "StopService")
End Sub
'***************************************************************************
Sub Script_Exit () 'reset all variables to nothing and exit script
set strComputer = nothing
set strProcess = nothing
set strService = nothing
set objWMIService = nothing
set colProcesses = nothing
set objShare = nothing
set objOutParams = nothing
set colItems = nothing
Wscript.quit 'exit script
End Sub
'***************************************************************************

+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Below is the VB I modified to check services on local or remote computers
+++++++++++++++++++++++++++++++++++++++++++++++++++++++

Here is the code I use in VB 2008 to check the process on the local or remote computer:

Imports System.Diagnostics
Public Class Form1

'=========================================================
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' display the list of running processes
UpdateProcessList()
End Sub

'=========================================================
''' Loop through the running processes, add each process name
''' to the process listbox
Private Sub UpdateProcessList()
' clear the existing list of any items
lstProcesses.Items.Clear()

' loop through the running processes and add
'each to the list
Dim p As System.Diagnostics.Process
Dim strComputer As String = txtComputer.Text

If strComputer = "" Then
'For Each p In System.Diagnostics.Process.GetProcesses()
For Each p In System.Diagnostics.Process.GetProcessesByName("winvnc4")
lstProcesses.Items.Add(p.ProcessName & " - " & p.Id.ToString())
Next
Else
'For Each p In System.Diagnostics.Process.GetProcesses(strComputer)
For Each p In System.Diagnostics.Process.GetProcesses(strComputer) 'where p.processname="winvnc4.exe"
lstProcesses.Items.Add(p.ProcessName & " - " & p.Id.ToString())
Next
End If
lstProcesses.Sorted = True
' display the number of running processes in
' a status message at the bottom of the page
tslProcessCount.Text = "Processes running: " & _
lstProcesses.Items.Count.ToString()


' display the number of running processes in
' a status message at the bottom of the page
tslProcessCount.Text = "Processes running: " & _
lstProcesses.Items.Count.ToString()
End Sub


'=========================================================
''' Manually update the list of runnings processes
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub btnUpdateProcessList_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnUpdateProcessList.Click
UpdateProcessList()

End Sub

'=========================================================
''' Kill the process selected in the process name and ID listbox
''' <param name="sender"></param>
''' <param name="e"></param>
Private Sub btnKill_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnKill.Click

If lstProcesses.SelectedItems.Count <= 0 Then
MessageBox.Show("Click on a process name to select it.", "No Process Selected")
Return
End If

' loop through the running processes looking for a match
' by comparing process name to the name selected in the listbox
Dim p As System.Diagnostics.Process

For Each p In System.Diagnostics.Process.GetProcesses()

Dim arr() As String = _
lstProcesses.SelectedItem.ToString().Split("-")

Dim sProcess As String = arr(0).Trim()
Dim iId As Integer = Convert.ToInt32(arr(1).Trim())

If p.ProcessName = sProcess And p.Id = iId Then
p.Kill()
End If

Next

' update the list to show the killed process
' has been removed
UpdateProcessList()

End Sub

'=========================================================
Private Sub btnComputer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnComputer.Click
UpdateProcessList()
End Sub

'=========================================================
End Class
 
Last edited:
additional effort / question

I tried the following: Added Refs to VB project for,
system.management - C:\Windows\microsoft.net\framework\v2.0.50727\system.management.dll
and
system.management.instrumentation - C:program files\reference assemblies\microsoft\framework\v3.5\system.management.instrumentation.dll

and tried the following code (taken almost verbatim from the vbs) Following (the code) are the errors I got when trying to run the form:

************************************************************
vb code begins below
************************************************************
Imports System
Imports System.Management
Imports System.Management.Instrumentation

Public Class frmVNC
Public Sub New()
'This call is required by the Windows Form Designer.
InitializeComponent()
End Sub
Dim strComputer
Dim strProcess = "'winvnc4.exe'"
Dim strService = "'winvnc4'"
Dim objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Dim colProcesses = objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE Name = " & strProcess & "")
Dim objShare = objWMIService.Get("Win32_Service.Name=" & strService & "")
Function isProcessRunning()
isProcessRunning = False
If colProcesses.count = 0 Then
isProcessRunning = False
Else
isProcessRunning = True
End If
End Function
Function Service_State()
Service_State = False
Dim objOutParams = objWMIService.execMethod("Win32_Service.Name=" & strService & "", "InterrogateService")
If objOutParams.returnvalue = 0 Then
Service_State = True
Else
Service_State = False
End If
End Function
Private Sub btnCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheck.Click
If Service_State() = True Then
Me.lblStatus.Text = strComputer & " " & strProcess & " is running"
End If
End Sub
End Class

**********************************************************
Error Below
**********************************************************

System.InvalidOperationException was unhandled
Message="An error occurred creating the form. See Exception.InnerException for details. The error is: Cannot create ActiveX component."
Source="RemoteVNC_WMI"
StackTrace:
at RemoteVNC_WMI.My.MyProject.MyForms.Create__Instance__[T](T Instance) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 190
at RemoteVNC_WMI.My.MyProject.MyForms.get_frmVNC()
at RemoteVNC_WMI.My.MyApplication.OnCreateMainForm() in (user_profile)\My Documents\Visual Studio 2008\Projects\RemoteVNC_WMI\My Project\Application.Designer.vb:line 35
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
at RemoteVNC_WMI.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Message="Cannot create ActiveX component."
Source="Microsoft.VisualBasic"
StackTrace:
at Microsoft.VisualBasic.Interaction.GetObject(String PathName, String Class)
at RemoteVNC_WMI.frmVNC..ctor() in (user_profile)\My Documents\Visual Studio 2008\Projects\RemoteVNC_WMI\Form1.vb:line 13
InnerException:
 
Last edited:
Solved

Added Refs to VB project for,
system.management - C:\Windows\microsoft.net\framework\v2.0.50727\syst em.management.dll
and
system.management.instrumentation - C:program files\reference assemblies\microsoft\framework\v3.5\system.managem ent.instrumentation.dll

'Created by Mike Adams July 2009
'You may use or modify this code provided
'that you agree to take full responsibility for
'any consequences it may have on your system
'under no circumstances will I or my company have
'any liability for your use of this code. It is provided
'as is without warranty or guarantee of any kind.

Imports System
Imports System.Management
Imports System.Management.Instrumentation

Public Class frmVNC
Dim Service_State As String = False 'status flag used to trigger events

Public Sub New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'check status of service and update lable
statusLBL()
End Sub


Private Sub btnCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCheck.Click
Dim strComputer As String = txtComputer.Text 're-declare variable to get new value from txt box
statusLBL()
End Sub

'this program uses the service instance which must be enclosed in ' ' marks
Private Sub statusLBL() 'to change service, simply substitute 'winvnc4' ex: 'desired service'
Dim strComputer As String = txtComputer.Text 'it is necessary to declare variables in each sub
Dim strService As String = "'winvnc4'" 'isn't assigned until after the form is created
Dim objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Dim objShare = objWMIService.Get("Win32_Service.Name=" & strService & "")
Dim objOutParams = objWMIService.execMethod("Win32_Service.Name=" & strService & "", "InterrogateService")

If objOutParams.returnvalue = 0 Then
Service_State = True
Me.lblStatus.BackColor = Color.Coral
Me.lblStatus.ForeColor = Color.DarkBlue
Me.lblStatus.Text = strService & " RUNNING on" & Chr(13) & strComputer & Chr(13) & Chr(13) & _
"Press YES to STOP?" & Chr(13) & "Press NO to exit!"
Else
Service_State = False
Me.lblStatus.BackColor = Color.Black
Me.lblStatus.ForeColor = Color.White
Me.lblStatus.Text = strService & " is OFF on " & Chr(13) & strComputer & Chr(13) & Chr(13) & _
"Press YES to Start?" & Chr(13) & "Press No to exit!"
End If
End Sub

Private Sub btnYes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnYes.Click

Dim strComputer As String = txtComputer.Text 'it is necessary to declare variables in each sub
Dim strService As String = "'winvnc4'" 'isn't assigned until after the form is created
Dim objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Dim objShare = objWMIService.Get("Win32_Service.Name=" & strService & "")
Dim objOutParams = objWMIService.execMethod("Win32_Service.Name=" & strService & "", "InterrogateService")

'service_state was set in 'sub statusLBL' used to trigger start or stop
If Service_State = True Then
objOutParams = objWMIService.ExecMethod("Win32_Service.Name=" & strService & "", "StopService")
statusLBL()
Else
objOutParams = objWMIService.ExecMethod("Win32_Service.Name=" & strService & "", "StartService")
statusLBL()
End If
End Sub

Private Sub btnNO_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNO.Click
Me.Close() 'user clicked no, close the form
End Sub
End Class
 
In response to private message (use forum to ask questions):
mla_ca520 said:
Sorry...I'm not incredibly familiar with VB and have used a WMI code creator (I found on the script guy's site) to write VBScripts for a variety of tasks. I was recently asked to figure out how to re-write those into VB executables so that we don't have scripts saved anywhere (easy to inject malicious code).

Anyway, I have to admit that I don't know what you mean that I should use System.management not wbem. Would you be willing to post an example so I can start to research what you are suggesting? I have looked for a few weeks to find a way of accomplishing this task without finding a solution or getting any responses. I finally got the final bit of code I posted to work on Friday but am definitely interested in learning a better way.

thanks,
Mike
In WMI Code Creator configure from menu 'Code Language', select VB.Net language and you get WMI code using the .Net classes instead of the scripting COM library.

Refer to help library for documentation, articles and code samples: System.Management Namespace ()

Search the web for example 'vb.net wmi' to find basic tutorials also.
 
Back
Top