在使用C#中的PowerShell中的Get-AppxPackage和Get-ItemProperty时,无法添加数据表。

huangapple go评论71阅读模式
英文:

When using Get-AppxPackage and Get-ItemProperty in powershell in C#, the datatable cannot be added

问题

我正在开发一个使用C#的WinForms应用程序。我尝试使用PowerShell的Get-AppxPackage和Get-ItemProperty来检索安装在PC上的软件信息(名称、版本)。从Get-ItemProperty检索到的信息在将其收集为集合后正确存储在一个DataTable中,并显示在一个DataGridView中。然而,从Get-AppxPackage检索到的名称和版本未被收集到集合中,导致计数为0。自然地,它们不会显示在DataTable或DataGridView中。

加载PowerShell的代码在两种情况下都是相同的,我只更改了命令值。那么为什么它不起作用呢?

以下是附加的代码。

private DataTable GetPrograms_1()
{
    DataTable programTable_1 = new DataTable();
    programTable_1.Columns.Add("Item Name");
    programTable_1.Columns.Add("Item Version");

    // Get-ItemProperty - UWP 
    string? command = "Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion";
    PowerShell powerShell = PowerShell.Create();
    powerShell.AddScript(command);

    // PowerShell
    Collection<PSObject> psObjects = powerShell.Invoke();

    // DataTable
    foreach (PSObject psObject in psObjects)
    {
        if (psObject.Properties["DisplayName"] != null && psObject.Properties["DisplayVersion"] != null)
        {
            string itemName = psObject.Properties["DisplayName"]?.Value?.ToString();
            string itemVersion = psObject.Properties["DisplayVersion"]?.Value?.ToString();

            programTable_1.Rows.Add(itemName, itemVersion);
        }
    }
    return programTable_1;
}

// UWP data
private DataTable GetPrograms_2()
{
    DataTable programTable_2 = new DataTable();
    programTable_2.Columns.Add("App Name");
    programTable_2.Columns.Add("App Version");

    // Get-AppxPackage - UWP
    string? command = "Get-AppxPackage -AllUsers | Select-Object Name, Version";
    PowerShell powerShell = PowerShell.Create();
    powerShell.AddScript(command);

    // PowerShell 
    Collection<PSObject> psObjects = powerShell.Invoke();

    // DataTable
    foreach (PSObject psObject in psObjects)
    {
        if (psObject.Properties["Name"]?.Value != null && psObject.Properties["Version"]?.Value != null)
        {
            string appName = psObject.Properties["Name"]?.Value?.ToString();
            string appVersion = psObject.Properties["Version"]?.Value?.ToString();

            programTable_2.Rows.Add(appName, appVersion);
        }
    }
    return programTable_2;
}

使用Get-AppxPackage是必要的。从CurrentVersion/Uninstall下的注册表中获取的数据无法替代从Get-AppxPackage获取的数据。目的是提取PC上的UWP应用程序的信息。要检索从Windows 11的"设置"->"应用"->"应用和功能"中获取的应用程序列表,必须使用Get-AppxPackage。

英文:

I am developing a WinForms application in C#. I am trying to retrieve software information (name, version) installed on the PC using PowerShell with Get-AppxPackage and Get-ItemProperty. The information retrieved from Get-ItemProperty is stored correctly in a DataTable after collecting it as a collection, and it is displayed in a DataGridView. However, the Name and Version retrieved from Get-AppxPackage are not being collected in the collection, resulting in a count of 0. Naturally, they are not being displayed in the DataTable or the DataGridView.

The code for loading PowerShell is the same in both cases, and I only changed the command values. So why isn't it working?

Here is the attached code.

private DataTable GetPrograms_1()
{
DataTable programTable_1 = new DataTable();
programTable_1.Columns.Add(&quot;Item Name&quot;);
programTable_1.Columns.Add(&quot;Item Version&quot;);

        // Get-ItemProperty - UWP 
        string? command = &quot;Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName, DisplayVersion&quot;;
        PowerShell powerShell = PowerShell.Create();
        powerShell.AddScript(command);

        // PowerShell
        Collection&lt;PSObject&gt; psObjects = powerShell.Invoke();

        //  DataTable
        foreach (PSObject psObject in psObjects)
        {
            if (psObject.Properties[&quot;DisplayName&quot;] != null &amp;&amp; psObject.Properties[&quot;DisplayVersion&quot;] != null)
            {
                string itemName = psObject.Properties[&quot;DisplayName&quot;]?.Value?.ToString();
                string itemVersion = psObject.Properties[&quot;DisplayVersion&quot;]?.Value?.ToString();

                programTable_1.Rows.Add(itemName, itemVersion);
            }
        }
        return programTable_1;
    }

    // UWP data
    private DataTable GetPrograms_2()
    {
        DataTable programTable_2 = new DataTable();
        programTable_2.Columns.Add(&quot;App Name&quot;);
        programTable_2.Columns.Add(&quot;App Version&quot;);

        // Get-AppxPackage - UWP
        string? command = &quot;Get-AppxPackage -AllUsers | Select-Object Name, Version&quot;;
        PowerShell powerShell = PowerShell.Create();
        powerShell.AddScript(command);

        // PowerShell 
        Collection&lt;PSObject&gt; psObjects = powerShell.Invoke();

        // DataTable
        foreach (PSObject psObject in psObjects)
        {
            if (psObject.Properties[&quot;Name&quot;]?.Value != null &amp;&amp; psObject.Properties[&quot;Version&quot;]?.Value != null)
            {
                string appName = psObject.Properties[&quot;Name&quot;]?.Value?.ToString();
                string appVersion = psObject.Properties[&quot;Version&quot;]?.Value?.ToString();

                programTable_2.Rows.Add(appName, appVersion);
            }
        }
        return programTable_2;
    }

Using Get-AppxPackage is necessary. The data from the registry under CurrentVersion/Uninstall cannot replace the data obtained from Get-AppxPackage. The purpose is to extract information about UWP applications on the PC. To retrieve the list of apps from "Settings" -&gt; "Apps" -&gt; "Apps & features" in Windows 11, Get-AppxPackage must be used.

答案1

得分: 1

我采用了直接通过 powershell.exe 执行 PowerShell 脚本,然后从标准输出中读取结果的方法。

// PowerShell 进程启动
Process process = new Process();
process.StartInfo.FileName = "powershell.exe";
process.StartInfo.Arguments = "-Command (Get-AppxPackage | Select-Object Name, Version)";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();

// 读取结果
string output = process.StandardOutput.ReadToEnd();

// 进程结束
process.WaitForExit();
英文:

I took the method of executing the PowerShell script directly via powershell.exe and then reading the results from standard output.

// PowerShell Process Start
Process process = new Process();
process.StartInfo.FileName =&quot;powershell.exe&quot;;
process.StartInfo.Arguments = $&quot;-Command (Get-AppxPackage | Select-Object Name, Version)&quot;;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.Start();

// Read Result
string output = process.StandardOutput.ReadToEnd();

// Process End
process.WaitForExit();

huangapple
  • 本文由 发表于 2023年7月10日 17:51:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/76652587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定