Pages

Friday, July 6, 2012

Please look over my methods. Best Practice?


I have an application that has multiple functions. Two in paticular will query a remote computer using WMI, and return the installed printers in a datagridview. The other is a new method that will query the remote computer using WMI, and return information about the RAM...
I don't want to repeat the code that populates the datagrideview each time I need to display info from a WMI call. So to acomadate for this, I changed the way the datagrideview is populated. It is now in a seperate class..
Im just wanting to know if this is the best solution.
Here is one of the methods that implements the new class I made. This method below will get the installed printers on the target machine:

 class remote_Info
 {

 public Form getPrinters(string target, Form print_Form) 
    {
    /**This will query the remote computer for the installed printers. 
     * It does this by using WMI and looking in Win32_Printer. 
     * 
     * */
    // Check to make sure no null arguments were passed 
    if (target == null | print_Form == null)
        throw new ArgumentNullException();

    // Define the dataTable and DataColumns 
    // The columns will server as the header in the datagrid 
    DataTable dt = new DataTable();
    DataColumn colName = new DataColumn("Name");
    DataColumn col_Driver = new DataColumn("Driver");
    DataColumn colLocation = new DataColumn("Location");
    dt.Columns.Add(colName);
    dt.Columns.Add(col_Driver);
    dt.Columns.Add(colLocation);          

    ManagementScope scope = new ManagementScope("\\\\" + target + "\\root\\cimv2");
    SelectQuery query = new SelectQuery("SELECT * FROM Win32_Printer");
    ManagementObjectSearcher mos = new ManagementObjectSearcher(scope, query);

    try
        {


        using (ManagementObjectCollection moc = mos.Get())
            {

            // Fire off a foreach loop. First creating a new data
            foreach (ManagementObject mo in moc)
                {
                try
                    {
                    DataRow row1 = dt.NewRow();
                    row1[colName] = mo["Name"] ?? "N/A";
                    row1[col_Driver] = mo["DriverName"] ?? "N/A";
                    row1[colLocation] = mo["Location"] ?? "N/A";
                    dt.Rows.Add(row1);
                    }
                finally
                    {
                    if (mo != null)
                        mo.Dispose();
                    }
                }
            }
        }
    catch(Exception ex)
        {
        writeLog(ex);
        MessageBox.Show("There was an error while processing your request. View the errorlog for more information");
        }

    display_Forms displayInstance = new display_Forms();            
    return  displayInstance.wmi_FillGrid("Printers", dt, print_Form);    

    }
 }

Now here is the class and method I made to fill the datagrideview. My idea is to use this each time I need to fill data from WMI into a datagrideview.

 class display_Forms{
public Form wmi_FillGrid(string title, DataTable dt, Form print_Form)
    {
    // Set the title of the form. 
    print_Form.Text = (title);
    print_Form.AutoSize = true;

    // Declare the datagrid view             
    DataGridView dataGrid = new DataGridView();
    // Datagrid Properties 
    dataGrid.BorderStyle = BorderStyle.None;
    dataGrid.BackgroundColor = SystemColors.GradientInactiveCaption;
    dataGrid.AutoSize = true;
    dataGrid.Width = 0;
    dataGrid.Height = 0;
    print_Form.Width = dataGrid.Width;
    print_Form.Height = dataGrid.Height;
    dataGrid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
    // Set the datasource to the Datatable
    dataGrid.DataSource = dt;

     // Add the datagrid to the form
    print_Form.Controls.Add(dataGrid);

    return print_Form;
    }
}
Just to show a full example, here is the calling method:

private void getInstalledPrinterListAtTargetToolStripMenuItem_Click(object sender, EventArgs e)
    {
    // This will query the list of installed printers on the target machine. 
    // Using WMI, it will query win32_Printers and loop through the returned list. 
    // This is all done on a seperate thread, finally returning the form in which the data is dispalyed. 
    // The form is called with begininvoke and displayed on the GUI thread. 

    string target = null;
    DialogResult results = custom_Forms.supperInputBox("Computer Name", "Enter Computer Name", ref target);
    if (results == System.Windows.Forms.DialogResult.Cancel)
        return;
    if (validation.validate(target) == false | validation.alphaNum(target) == false)
        return;
    // Declare the local objects 
    remote_Info info = new remote_Info();      
    Form print_Form = new Form(); 

    // Execute the query on a seperate thread. Wrapping in a try/catch/finally block
    // The finally statement will display the returned Form from the getPrinters method.

    (new System.Threading.Thread(() =>
    {
    try
        {
        print_Form = info.getPrinters(target, print_Form);
        }
    catch (Exception ex)
        {
        writeLog(ex);
        return;
        }
    finally
        {

        this.BeginInvoke((Action)delegate
            {
            if(print_Form != null)
            print_Form.Show();
            });

        }

    })).Start();


    print_Form = info.getPrinters(target, print_Form);
    print_Form.Show();

    }

No comments:

Post a Comment