Powershell-string to listview

本文关键字:listview to Powershell-string | 更新日期: 2023-09-27 18:06:15

我创建了一个c#应用程序,除其他外,它应该通过使用powershell代码将已安装的程序获取到远程计算机上。我可以运行代码,但它只将项目添加到单行中的单列,我不能在其中滚动。

你能告诉我如何将每个程序添加到新行,其中标题是:程序,供应商,版本?以下是ps1代码:

Invoke-Command -ComputerName $computername -ScriptBlock {
    $SWInstalled = get-wmiobject Win32_product | select @{Label="Program";Expression={$_.Name}}, version, vendor | Sort-Object Program
    $SWInstalled | ft
}
下面是相关的c#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.IO;
namespace ClientCheck
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string RunScript(string scriptText)
        {
            // create Powershell runspace 
            Runspace runspace = RunspaceFactory.CreateRunspace();
            // open it 
            runspace.Open();
            runspace.SessionStateProxy.SetVariable("ComputerName", CompnameInput.Text);
            runspace.SessionStateProxy.SetVariable("user", UserNameInput.Text);
            // create a pipeline and feed it the script text 
            Pipeline pipeline = runspace.CreatePipeline();
            pipeline.Commands.AddScript(scriptText);
            // add an extra command to transform the script output objects into nicely formatted strings 
            // remove this line to get the actual objects that the script returns. For example, the script 
            // "Get-Process" returns a collection of System.Diagnostics.Process instances. 
            pipeline.Commands.Add("Out-String");
            // execute the script 
            Collection<PSObject> results = pipeline.Invoke();
            // close the runspace 
            runspace.Close();
            // convert the script result into a single string 
            StringBuilder stringBuilder = new StringBuilder();
            foreach (PSObject obj in results)
            {
                stringBuilder.AppendLine(obj.ToString());
            }
            // return the results of the script that has 
            // now been converted to text 
            return stringBuilder.ToString();
        }
        // helper method that takes your script path, loads up the script 
        // into a variable, and passes the variable to the RunScript method 
        // that will then execute the contents 
        private string LoadScript(string filename)
        {
            try
            {
                // Create an instance of StreamReader to read from our file. 
                // The using statement also closes the StreamReader. 
                using (StreamReader sr = new StreamReader(filename))
                {
                    // use a string builder to get all our lines from the file 
                    StringBuilder fileContents = new StringBuilder();
                    // string to hold the current line 
                    string curLine;
                    // loop through our file and read each line into our 
                    // stringbuilder as we go along 
                    while ((curLine = sr.ReadLine()) != null)
                    {
                        // read each line and MAKE SURE YOU ADD BACK THE 
                        // LINEFEED THAT IT THE ReadLine() METHOD STRIPS OFF 
                        fileContents.Append(curLine + "'n");
                    }
                    // call RunScript and pass in our file contents 
                    // converted to a string 
                    return fileContents.ToString();
                }
            }
            catch (Exception e)
            {
                // Let the user know what went wrong. 
                string errorText = "The file could not be read:";
                errorText += e.Message + "'n";
                return errorText;
            }

        private void GetSWButton_Click(object sender, RoutedEventArgs e)
        {
            SWList.Items.Clear();
            SWList.Items.Add((RunScript(LoadScript(@"C:'Get_Installed_Software.ps1"))));
        }
    }
}

还有,这里是XAML代码:

<ListView x:Name="SWList" Height="404" Margin="36,169,36,51" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" ScrollViewer.HorizontalScrollBarVisibility="Disabled" BorderThickness="0" Visibility="Hidden" Grid.Row="2">
    <ListView.RenderTransform>
        <TransformGroup>
            <ScaleTransform/>
            <SkewTransform AngleX="-0.0"/>
            <RotateTransform/>
            <TranslateTransform X="0.346"/>
        </TransformGroup>
    </ListView.RenderTransform>
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Program" DisplayMemberBinding ="{Binding 'Program'}" Width="440"/>
            <GridViewColumn Header="Vendor" DisplayMemberBinding="{Binding 'Vendor'}" Width="281"/>
            <GridViewColumn Header="Version" DisplayMemberBinding ="{Binding 'Version'}" Width="150"/>
        </GridView>
    </ListView.View>
</ListView>

Powershell-string to listview

看起来您正在遍历PSObject结果并将它们附加到单个StringBuilder中。当您将RunScript的结果添加到SWList项时,您只添加了单个字符串。这就是为什么它只出现在一行中。

正如Mike在他的评论中指出的那样,通过在脚本末尾使用Format-Table cmd命令,您正在撤消由PowerShell生成的漂亮对象属性;这几乎可以肯定是导致它显示在单列中的原因。

下面是一个更新的RunScript方法的例子,它返回一个对象集合而不是单个字符串。请注意我是如何更改方法签名以返回PSObjects的Collection而不仅仅是字符串的。我还注释掉了将out - string添加到管道末尾的行。这意味着您将获得从该函数返回的原始PSObjects。根据您运行的脚本,这些psoobject的BaseObject将是不同的类型。您可以访问这些psoobject对象的BaseObject属性来获取所需的值。

private Collection<PSObject> RunScript(string scriptText)
    {
        // create Powershell runspace 
        Runspace runspace = RunspaceFactory.CreateRunspace();
        // open it 
        runspace.Open();
        runspace.SessionStateProxy.SetVariable("ComputerName", CompnameInput.Text);
        runspace.SessionStateProxy.SetVariable("user", UserNameInput.Text);
        // create a pipeline and feed it the script text 
        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(scriptText);
        // add an extra command to transform the script output objects into nicely formatted strings 
        // remove this line to get the actual objects that the script returns. For example, the script 
        // "Get-Process" returns a collection of System.Diagnostics.Process instances. 
      //  pipeline.Commands.Add("Out-String");
        // execute the script 
        Collection<PSObject> results = pipeline.Invoke();
        // close the runspace 
        runspace.Close();
        return results;

}