c# - 如何通过 IP 地址列出网络计算机上所有已安装的软件?

标签 c# registry office-interop

我想知道如何获取安装在网络计算机上的软件列表。

我能够获得为我的本地计算机安装的软件列表,但不确定如何提取网络内计算机上安装软件的详细信息。

我正在使用服务器名称或网络计算机的 IP 地址作为唯一输入。

下面是从本地机器获取已安装软件的详细信息的代码(到目前为止我已经实现):

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;
    }
}

请帮助并指导我实现这一目标。 预先感谢您查看此问题并花费宝贵的时间。

最佳答案

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;
        }

从上面的代码,现在我可以列出远程计算机上安装的所有软件。感谢大家的帮助和支持。

关于c# - 如何通过 IP 地址列出网络计算机上所有已安装的软件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24568130/

相关文章:

c - RegSetValueExA() 函数在 C 中的注册表项名称中放置方 block

ms-office - 在 Windows 服务器上安装 Microsoft Office?

c# - 单击按钮时 WPF 中的数据绑定(bind)

c# - 更新[2] - ASP.NET Core Web API上传和下载文件 - Stream异常

c# - 如何以编程方式更改 Word 2010 文档的布局?

excel - 从我的插件自定义 Office(Word/Excel/PowerPoint)标准工具栏、功能区、菜单和上下文菜单

c# - 如何创建无需管理员权限即可部署的 Office COM 加载项

c# - .Distinct() 的更快替代品

java - 如何在java中读取注册表

c - RegGetValue(), header <winreg.h> 在 c 中不起作用