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>
看起来您正在遍历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;
}