背景
一个客户想要在WPF中查找所有安装的Windows Store App,但是如果是编程来写,只能用UWP的类库,不支持WPF。
经过研究发现,使用PowerShell的脚本Get-AppxPackage -AllUsers
可以获得所有的用户账号下安装过的Store App。
相关链接:Get-AppxPackage
所以本文的宗旨就是使用.NET的类库来调用PowerShell的脚本。
类库路径
原因
之所以有这个话题是因为当时我自己用的测试项目是基于.NET 4.6的WPF,但是客户的是.NET 4.0的WPF项目,用我的路径找到的类库是会遇到编译错误。
正确路径
.NET 4.5版本及以上:C:\Program Files(x86)\Reference Assemblies\Microsoft\WindowsPowerShell\3.0\System.Management.Automation.dll
其他.NET版本:C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll
具体实现
根据项目基于的.NET版本,加入相应的
System.Management.Automation.dll
.首先我们建立一个Runspace,这个是用来维护pipelines之间的状态(state)的。
1
Runspace rs;
这个是由于我们之后会建立一个叫PowerShell的实例,这个实例就属于一个Pipeline,这样我们可以在这个Runspace中管理我们建立的PowerShell的运行状态等。
之后我们可以在WPF的页面的实例化代码中建立这个Runspace.
1
2
3
4
5
6public MainWindow()
{
InitializeComponents();
rs = RunspaceFactory.CreateRunspace();
rs.Open();
}之后可以在ButtonClick或者其他事件中去调用PowerShell的命令,如下:
1
2
3
4
5
6
7
8
9private void Button_Click(object sender, RoutedEventArgs e)
{
PowerShell ps = PowerShell.Create();
// 给这个ps的Runspace赋值
// 为刚才的rs
ps.Runspace = rs;
ps.AddCommand("Get-AppxPackage").AddParameter("AllUsers");
Collection<PSObject> returnedObject = ps.Invoke();
}
至此,我们完成了对这个PowerShell命令的调用。
延申问题
在运行这个代码的时候,会得到一个报错,如下:
这个问题涉及到运行命令的权限。我们通常知道每个命令都有一些权限,是根据restriction permission来决定的,是一个系统的设置。
但是这边这个问题不是,原因是因为即便你用默认的权限,也可以运行这条命令。并且在PowerShell客户端也会报这个错。
这个错是由于运行的时候的软件要以Admin的形式来运行,原因是我们在query所有这台机器下所有用户安装的store app,只有admin才有权限访问其他用户安装的内容信息。
所以要Debug这个程序,需要用Admin来运行build生成的exe文件,然后使用VS的Debug菜单中的Attach To Process来附加到进程上来做断点调试。
评论