period. If this is the case, an event will be triggered only when the state at the end of the period differs
from the state at the beginning of the period. For example, no event is raised if a process is started
and then stopped within a single polling interval.
The event handler constructs a new
ManagementBaseObject from a value passed into
the event arguments to obtain the display name and
executable path of the new process. Since UI controls
can only be updated from the UI thread, you cannot
directly update the ListBox. Instead you must call
BeginInvoke to execute the LogNewProcess function
on the UI thread. Figure 9-9 shows the form in action.
Message queues
The Message Queues node, expanded in Figure 9-10, gives you access to the message queues
available on your computer. You can use three types of queues: private, which will not appear when
a foreign computer queries your computer; public, which will appear; and system, which is used for
unsent messages and other exception reporting.
fiGure 9-9
To use the Message Queues node, you need to ensure that MSMQ is installed on
your computer. You can do this via Programs and Features in the Control Panel.
Select the Turn Windows Features On or Off task menu item and then select the
checkbox to enable the Microsoft Message Queue (MSMQ) Server feature.
In Figure 9-10, a message queue called samplequeue has been added
to the Private Queues node by selecting Create Queue from the
right-click context menu. Once you have created a queue, you can
create a properly configured instance of the MessageQueue class
by dragging the queue onto a new Windows Form. To demonstrate
the functionality of the MessageQueue object, add two TextBoxes
and a button to the form, laid out as shown in Figure 9-11. The
Send button is wired up to use the MessageQueue object to send the
message entered in the first textbox. In the Load event for the form,
a background thread is created that continually polls the queue to
retrieve messages, which will populate the second textbox:
c#
public Form4()
{
InitializeComponent();
var monitorThread = new System.Threading.Thread(MonitorMessageQueue);
fiGure 9-10
168 .
chaPter 9 SerVer explorer
monitorThread.IsBackground = true;
monitorThread.Start();
this.Button1.Click +=new EventHandler(btn_Click);
}
private void btn_Click(object sender, EventArgs e)
{
this.messageQueue1.Send(this.TextBox1.Text);
}
private void MonitorMessageQueue()
{
var m = default(System.Messaging.Message);
while (true)
{
try
{
m = this.messageQueue1.Receive(new TimeSpan(0, 0, 0, 0, 50));
this.ReceiveMessage((string)m.Body);
}
catch (System.Messaging.MessageQueueException ex)
{
if (!(ex.MessageQueueErrorCode ==
System.Messaging.MessageQueueErrorCode.IOTimeout))
{
throw ex;
}
}
System.Threading.Thread.Sleep(10000);
}
}
private delegate void MessageDel(string msg);
private void ReceiveMessage(string msg)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MessageDel(ReceiveMessage), msg);
return;
}
this.TextBox2.Text = msg;
}
Code snippet Form4.cs
Vb
Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles Me.Load
Dim monitorThread As New Threading.Thread(AddressOf MonitorMessageQueue)
monitorThread.IsBackground = True
monitorThread.Start()
End Sub
server Connections .
169
Private Sub btn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click
Me.MessageQueue1.Send(Me.TextBox1.Text)
End Sub
Private Sub MonitorMessageQueue()
Dim m As Messaging.Message
While True
Try
m = Me.MessageQueue1.Receive(New TimeSpan(0, 0, 0, 0, 50))
Me.ReceiveMessage(m.Body)
Catch ex As Messaging.MessageQueueException
If Not ex.MessageQueueErrorCode = _
Messaging.MessageQueueErrorCode.IOTimeout Then
Throw ex
End If
End Try
Threading.Thread.Sleep(10000)
End While
End Sub
Private Delegate Sub MessageDel(ByVal msg As String)
Private Sub ReceiveMessage(ByVal msg As String)
If Me.InvokeRequired Then
Me.BeginInvoke(New MessageDel(AddressOf ReceiveMessage), msg)
Return
End If
Me.TextBox2.Text = msg
End Sub
Code snippet Form4.vb
Note in this code snippet that the background thread is
never explicitly closed. Because the thread has the
IsBackground property set to True, it is automatically
terminated when the application exits. As with the
previous example, because the message processing is done
in a background thread, you need to switch threads when
you update the user interface using the BeginInvoke
method. Putting this all together, you get a form like the
one shown in Figure 9-11.
As messages are sent to the message queue, they appear
under the appropriate queue in Server Explorer. Clicking
the message displays its contents in the Properties window.
Performance counters
One of the most common things developers forget to consider when building an application is how
it will be maintained and managed. For example, consider an application that was installed a year
fiGure 9-11
170 .
chaPter 9 SerVer explorer
ago and has been operating without any issues. All
of a sudden, requests start taking an unacceptable
amount of time. It is clear that the application is not
behaving correctly, but there is no way to determine
the cause of the misbehavior. One strategy for
identifying where the performance issues are is
to use performance counters. Windows has many
built-in performance counters that can be used to
monitor operating system activity, and a lot of third-
party software also installs performance counters so
administrators can identify any rogue behavior.
The Performance Counters node in the Server
Explorer tree, expanded in Figure 9-12, has two
primary functions. First, it enables you to view
and retrieve information about the currently
installed counters. You can also create new
performance counters, as well as edit or delete existing counters. As you can see in Figure 9-12,
under the Performance Counters node is a list of categories and under those is a list of counters.
fiGure 9-12
You must be running Visual Studio with Administrator rights to view the
Performance Counters under the Server Explorer.
To edit either the category or the counters, select
Edit Category from the right-click context menu
for the category. To add a new category and
associated counters, right-click the Performance
Counters node and select Create New Category
from the context menu. Both of these operations
use the dialog shown in Figure 9-13. Here, a new
performance counter category has been created
that will be used to track a form’s open and
close events.
The second function of the Performance Counters
section is to provide an easy way for you to access
performance counters via your code. By dragging
a performance counter category onto a form, you
gain access to read and write to that performance
counter. To continue with this chapter’s example,
drag the new My Application performance
counters, Form Open and Form Close, onto a new
fiGure 9-13
Windows Form. Also add a couple of textboxes and a button so you can display the performance
counter values. Finally, rename the performance counters so they have friendly names. This should
give you a form similar to the one shown in Figure 9-14.
server Connections .
171
fiGure 9-14
In the properties for the selected performance counter, you can see that the appropriate counter — in
this case, Form Close — has been selected from the My Application category. You will also notice a
MachineName property, which is the computer from which you are retrieving the counter information,
and a ReadOnly property, which needs to be set to False if you want to update the counter. (By
default, the ReadOnly property is set to True.) To complete this form, add the following code to the
Retrieve Counters button click event handler:
c#
this.textBox1.Text = this.perfFormOpen.RawValue.ToString();
this.textBox2.Text = this.perfFormClose.RawValue.ToString();
Code snippet Form5.cs
Vb
Me.textBox1.Text = Me.perfFormOpen.RawValue
Me.textBox2.Text = Me.perfFormClose.RawValue
Code snippet Form5.vb
You also need to add code to the application to update the performance counters. For example, you
might have the following code in the Form Load event handlers:
c#
this.perfFormOpen.Increment();
Vb
Me.perfFormOpen.Increment()
When you dragged the performance counter onto the form, you may have noticed a smart tag (small
arrow that appears near the top-right corner when a control is selected) on the performance counter
172 .
chaPter 9 SerVer explorer
component that had a single item, Add Installer. When the component is selected, as in
Figure 19-14, you will notice the same action at the bottom of the Properties window. Clicking
this action in either place adds an Installer class to your solution that can be used to install the
performance counter as part of your installation process. Of course, for this installer to be called,
the assembly it belongs to must be added as a custom action for the deployment project. For more
information on custom actions, see Chapter 48.
Prior to Visual Studio 2008, you needed to manually modify the installer to create multiple
performance counters. In the current version, you can simply select each additional performance
counter and click Add Installer. Visual Studio 2010 will direct you back to the first installer that
was created and will have automatically added the second counter to the Counters collection of the
PerformanceCounterInstaller component, as shown in Figure 9-15.
fiGure 9-15
You can also add counters in other categories by adding
additional PerformanceCounterInstaller components
to the design surface. You are now ready to deploy your
application with the knowledge that you will be able to use
a tool such as PerfMon to monitor how your application is
behaving.
services
The Services node, expanded in Figure 9-16, shows the
registered services for the computer. Each node indicates
the state of that service in the bottom-right corner of the
icon. Possible states are Stopped, Running, or Paused.
Selecting a service displays additional information about the
service, such as other service dependencies, in the Properties
fiGure 9-16
window.
Data Connections .
173
As with other nodes in the Server Explorer, each service can be dragged onto the design surface
of a form. This generates a ServiceController component in the nonvisual area of the form. By
default, the ServiceName property is set to the service that you dragged across from the Server
Explorer, but this can be changed to access information and control any service. Similarly, the
MachineName property can be changed to connect to any computer to which you have access. The
following code shows how you can stop a Service using ServiceController component:
c#
this.serviceController1.Refresh();
if (this.serviceController1.CanStop)
{
if (this.serviceController1.Status ==
System.ServiceProcess.ServiceControllerStatus.Running)
{
this.serviceController1.Stop();
this.serviceController1.Refresh();
}
}
Code snippet Form6.cs
Vb
Me.ServiceController1.Refresh()
If Me.ServiceController1.CanStop Then
If Me.ServiceController1.Status = _
ServiceProcess.ServiceControllerStatus.Running Then
Me.ServiceController1.Stop()
Me.ServiceController1.Refresh()
End If
End If
Code snippet Form6.vb
In addition to the three main states — Running, Paused, or Stopped — other transition states
are ContinuePending, PausePending, StartPending, and StopPending. If you are about to start a
service that may be dependent on another service that is in one of these transition states, you can
call the WaitForStatus method to ensure that the service will start properly.
data connections
The Data Connections node allows you to connect to a database and perform a large range of
administrative functions. You can connect to a wide variety of data sources including any edition
of SQL Server, Microsoft Access, Oracle, or a generic ODBC data source. Figure 9-17 shows the
Server Explorer connected to a SQL Server database file.
174 .
chaPter 9 SerVer explorer
The Server Explorer provides access to the Visual
Database, which will allow you to perform a large range of
administrative functions on the connected database. You can
create databases, add and modify tables, views, and stored
procedures, manage indexes, execute queries, and much
more. Chapter 26 covers all aspects of the Data Connections
functionality.
sharePoint connections
New to Visual Studio 2010 is the ability to connect to a
Microsoft Office SharePoint Server with the Server Explorer.
This feature allows you to navigate and view many of the
SharePoint resources and components.
The Server Explorer only provides read-only access to
SharePoint resources — you cannot, for example, create or
edit a list definition. Even so, it can be useful to have ready
access to this information in Visual Studio when developing a
SharePoint application. As with many of the components under the Servers Node you can also drag
and drop certain SharePoint resources directly onto the design surface of your SharePoint project.
Using the Server Explorer to browse SharePoint resources is covered in detail in Chapter 24.
suMMary
In this chapter you learned how the Server Explorer can be used to manage and work with computer
resources and services. Chapter 22 continues the discussion on the Server Explorer, covering