How can you list all of the installed software on

2020-06-28 02:17发布

问题:

I'd like to know how to get a list of the software installed on computers on a network.

I am able to get the list of software installed for my local machine, but am not sure of how I can extract the details of installed software on the computers within the network.

I am using the server name or the IP address of the network computer as the only input.

Below is the code (which I had implemented until now) which is getting the details of installed software from the local machine:

const string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

private void ListSoftwareInstalled(string servername)
{
    var result = new List<string>();
    result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry32));
    result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry64));

    if (result != null && result.Count > 0)
    {
        // Convert to DataTable.
        DataTable table = ConvertListToDataTable(result);
        foreach (var column in table.Columns.Cast<DataColumn>().ToArray())
        {
            if (table.AsEnumerable().All(dr => dr.IsNull(column)))
                table.Columns.Remove(column);
        }
        table.Columns["Column1"].ColumnName = "Installed Software";
        GenerateExcel(table);
    }
}


private DataTable ConvertListToDataTable(List<string> result)
{
    // New table.
    DataTable table = new DataTable();

    // Get max columns.
    int columns = 0;
    foreach (var array in result)
    {
        if (array.Length > columns)
            columns = array.Length;
    }

    // Add columns.
    for (int i = 0; i < columns; i++)
        table.Columns.Add();

    // Add rows.
    foreach (var array in result)
        table.Rows.Add(array);

    return table;
}

private static IEnumerable<string> GetInstalledProgramsFromRegistry(RegistryView registryView)
{
    var result = new List<string>();

    using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registry_key))
    {
        foreach (string subkey_name in key.GetSubKeyNames())
        {
            using (RegistryKey subkey = key.OpenSubKey(subkey_name))
            {
                if (IsProgramVisible(subkey))
                {
                    result.Add((string)subkey.GetValue("DisplayName"));
                }
            }
        }
    }
    return result;
}

private static bool IsProgramVisible(RegistryKey subkey)
{
    var name = (string)subkey.GetValue("DisplayName");
    var releaseType = (string)subkey.GetValue("ReleaseType");
    //var unistallString = (string)subkey.GetValue("UninstallString");
    var systemComponent = subkey.GetValue("SystemComponent");
    var parentName = (string)subkey.GetValue("ParentDisplayName");

    return !string.IsNullOrEmpty(name) &&
            string.IsNullOrEmpty(releaseType) &&
            string.IsNullOrEmpty(parentName) &&
            (systemComponent == null);
}

private void GenerateExcel(DataTable dt)
{
    XL.Application oXL;
    XL._Workbook oWB;
    XL._Worksheet oSheet;
    XL.Range oRng;

    try
    {
        oXL = new XL.Application();
        Application.DoEvents();
        oXL.Visible = false;
        //Get a new workbook.
        oWB = (XL._Workbook)(oXL.Workbooks.Add(Missing.Value));
        oSheet = (XL._Worksheet)oWB.ActiveSheet;
        //System.Data.DataTable dtGridData=ds.Tables[0];
        int iRow = 2;
        if (dt.Rows.Count > 0)
        {
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                oSheet.Cells[1, j + 1] = dt.Columns[j].ColumnName;
            }
            // For each row, print the values of each column.
            for (int rowNo = 0; rowNo < dt.Rows.Count; rowNo++)
            {
                for (int colNo = 0; colNo < dt.Columns.Count; colNo++)
                {
                    oSheet.Cells[iRow, colNo + 1] = dt.Rows[rowNo][colNo].ToString();
                }
                iRow++;
            }
            iRow++;
        }
        oRng = oSheet.get_Range("A1", "IV1");
        oRng.EntireColumn.AutoFit();
        oXL.Visible = true;
    }
    catch (Exception theException)
    {
        throw theException;
    }
    finally
    {
        oXL = null;
        oWB = null;
        oSheet = null;
        oRng = null;
    }
}

Please help and guide me towards achieving this. Thanks in advance for looking it in to this Question and spending your valuable time.

回答1:

private static List<string> ReadRemoteRegistryusingWMI(string machineName)
        {
        List<string> programs = new List<string>();

        ConnectionOptions connectionOptions = new ConnectionOptions();
        connectionOptions.Username = @"*******";
        connectionOptions.Password = "*******";
        //connectionOptions.Impersonation = ImpersonationLevel.Impersonate;
        ManagementScope scope = new ManagementScope("\\\\" + machineName + "\\root\\CIMV2", connectionOptions);
        scope.Connect();

        string softwareRegLoc = @"Software\Microsoft\Windows\CurrentVersion\Uninstall";

        ManagementClass registry = new ManagementClass(scope, new ManagementPath("StdRegProv"), null);
        ManagementBaseObject inParams = registry.GetMethodParameters("EnumKey");
        inParams["hDefKey"] = 0x80000002;//HKEY_LOCAL_MACHINE
        inParams["sSubKeyName"] = softwareRegLoc;

        // Read Registry Key Names 
        ManagementBaseObject outParams = registry.InvokeMethod("EnumKey", inParams, null);
        string[] programGuids = outParams["sNames"] as string[];

        foreach (string subKeyName in programGuids)
            {
            inParams = registry.GetMethodParameters("GetStringValue");
            inParams["hDefKey"] = 0x80000002;//HKEY_LOCAL_MACHINE
            inParams["sSubKeyName"] = softwareRegLoc + @"\" + subKeyName;
            inParams["sValueName"] = "DisplayName";
            // Read Registry Value 
            outParams = registry.InvokeMethod("GetStringValue", inParams, null);

            if (outParams.Properties["sValue"].Value != null)
                {
                string softwareName = outParams.Properties["sValue"].Value.ToString();
                programs.Add(softwareName);
                }
            }

        return programs;
        }

From the above code , Now i am able to List out all the software installed on Remote computer.Thanks all of you for your help and Support.