I have a simple form with two buttons (Start and Stop) and a DataGridView. I am trying to populate the DataGridView with the results of a WMI query that enumerates Win32_Process instances and puts all process names in the only column of the DataGridView. The code looks like this:
using System;
using System.Management;
using System.Windows.Forms;
namespace WindowsFormsApplication10
{
public partial class Form1 : Form
{
ManagementObjectSearcher Searcher =
new ManagementObjectSearcher();
SelectQuery Query = new SelectQuery();
ManagementOperationObserver Observer =
new ManagementOperationObserver();
public Form1()
{
InitializeComponent();
Observer.Completed +=
new CompletedEventHandler(Observer_Completed);
Observer.ObjectReady +=
new ObjectReadyEventHandler(Observer_ObjectReady);
Grid.ColumnCount = 1;
Grid.Columns[0].Name = "Name";
}
private void Start_Click(object sender, EventArgs e)
{
Query.QueryString = "Select * From Win32_Process";
Searcher.Query = Query;
Searcher.Get(Observer);
}
private void Observer_Completed
(object sender, CompletedEventArgs e)
{
Grid.Refresh();
}
private void Observer_ObjectReady
(object sender, ObjectReadyEventArgs e)
{
string [] row = new string []
{e.NewObject["Name"].ToString()};
Grid.Rows.Add(row);
Grid.Refresh();
}
private void stop_Click(object sender, EventArgs e)
{
Observer.Cancel();
}
}
}
When I run the code using the 'Start Debugging' option it runs fine and pop开发者_StackOverflow社区ulates the DataGridView. One strange thing (at least to me) I noticed is that in the Observer_ObjectReady the Grid.Refresh() line is never reached. When I run the code with 'Start Without Debugging' the DataGridView is populated but the form freezes immediately after that. How can I deal with this? (Sorry if this is not enough information - I am willing to provide more if necessary, but, as you might have noticed, I don't have much experience with C# or Visual Studio).
You shouldn't to add a row to your GridView everytime you receive a new entry. You could to load all your processes into a collection and them to bind it to your control.
I just found this link and reading its source code can help you to achieve your objective: Manage Processes on Remote Machine
Could it be an Exception is being thrown? Winforms don't just halt execution when an exception is thrown, that method is aborted and an event that you have to manually handle is raised. You'll have to create an exception handler to see them!
Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
My guess is that you're getting an exception from something -- it could be that not calling .Connect() on the ManagementScope that you're also not creating is giving you a problem... the following is a portion of what I'm using and it works for me in asynchronous mode. YMMV.
ManagementScope ms = new ManagementScope(@"\\localhost\root\cimv2\");
ms.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(ms, query);
searcher.Get(observer);
Also, as Rubens said, the problem may be with the data grid and adding one row at a time. Have you considered adding the items to a collection in the observer's ObjectReady event, and then data binding to them in the observer's Completed event?
A third possibility could be a combination of the exceptions not being surfaced and the callback events being made from a non-UI thread -- Attempting to update UI controls from another thread is a big no-no. See "How do I make event callbacks into my winforms thread safe?"
Hope something there is helpful to you. :-)
精彩评论