Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run PowerShell in x64 or x86 using C#?

Tags:

c#

powershell

I'm using this C# code to read my installed programs using PowerShell.

I need it to read both x64 and x86 registry through PowerShell, how am I doing this?

Is there a way to redirect? or maybe run PowerShell in x64 and then x86?

public void conf() {
process p1 = new Process();
ProcessStartInfo psi1 = new ProcessStartInfo("powershell", "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName");
psi1.RedirectStandardOutput = true;
psi1.CreateNoWindow = true;
p1.StartInfo = psi1;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.Verb = "runas";
p1.Start();
string output = p1.StandardOutput.ReadToEnd();
Console.WriteLine(output);
p1.WaitForExit(400);
}
like image 219
Tom S Avatar asked Apr 12 '16 08:04

Tom S


People also ask

How do I run PowerShell 64 bit?

The 64-bit version of PowerShell (the one that 64-bit Windows opens by default) is located under: “C:\Windows\SysWOW64\WindowsPowerShell\v1. 0.” To run the program as administrator, right-click on powershell.exe and then choose the “Run as administrator” option.

How do I run PowerShell code?

In File Explorer (or Windows Explorer), right-click the script file name and then select "Run with PowerShell". The "Run with PowerShell" feature starts a PowerShell session that has an execution policy of Bypass, runs the script, and closes the session.


1 Answers

This should do if your process is running in x64 (or it's an x86 process running on an x86 OS).

bool is64 = IntPtr.Size == 8;
var cmdline = "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* " 
       + (is64 ? ",HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*" : "") 
       + " | Select-Object DisplayName";
ProcessStartInfo psi1 = new ProcessStartInfo("powershell", cmdline);

This won't work if the process is a 32-bit process running on an x64 OS, but for .NET, it should work with AnyCPU as long as you don't choose "prefer 32-bit"

Update

If you are only aiming at getting the display names, there might be "display-name duplicates" (in both registry keys)... so you can just remove them from the output. This will remove duplicates and sort:

var result = new StringBuilder();
var resultArr = output.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Distinct().ToArray();
Array.Sort(resultArr, StringComparer.InvariantCulture);
foreach (string s in resultArr)
    result.AppendLine(s);
output = result.ToString(); 

Update 2

If you don't want to mangle with processes and capturing output, you can install the System.Management.Automation nuget package and use powershell directly.

The whole equivalent program would be:

PowerShell ps = PowerShell.Create();
ps.AddCommand("Get-ItemProperty");
var parm = new List<string> {
     @"HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
};
if(IntPtr.Size == 8)
  parm.Add(@"HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*");
var pso = ps.Invoke(parm);
var result = new StringBuilder();
foreach (var ob in pso)
{
  if(ob.Members["DisplayName"] != null)
    result.AppendLine(ob.Members["DisplayName"].Value.ToString());
}
Console.WriteLine(result.ToString());

This should be better than calling the process :-)

like image 133
Jcl Avatar answered Oct 21 '22 23:10

Jcl