1

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 populates 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).

2 Answers2

0

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

Rubens Farias
  • 57,174
  • 8
  • 131
  • 162
  • Thank you for the answer. That application uses synchronous enumaration, and I have also been able to make it work that way. My problem is that it can take a lot of time when enumerating classes like CIM_DataFile or Win32_Directory. This is why I am attempting to use the asynchronous enumeration (using ManagementOperationObserver.ObjectReady event) but I cant make it work - the application freezes. –  Dec 10 '09 at 22:13
  • do you need to display all data? can you somehow paginate it? – Rubens Farias Dec 10 '09 at 22:23
  • Sometimes I will need to display all the data. The synchronous enumeration works well but for Cim_DataFile asynchronous enumeration would be the right choice. I have been able to use the same asynchronous code and send the data to a RichTextBox, but I would also like to be able to populate a DataGridView. I suppose this has to do with a DataGridView, but I am puzzled because I don't get any exceptions, the application just freezes, while the same application works fine when I replace the DataGridView with a RichTextBox and add lines of text from Observer_ObjectReady. –  Dec 11 '09 at 15:42
0

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. :-)

Community
  • 1
  • 1
BrainSlugs83
  • 6,214
  • 7
  • 50
  • 56