当Powershell作为32位进程运行时,我不知道有什么机制可以将其“切换”到64位模式。64位系统中虚拟化支持的整个重点是使32位进程相信它们正在运行在32位操作系统中...
然而,我过去使用了以下技术,对我非常有效(以下代码在带有Powershell v1的Vista SP1 x64上进行了测试)。该技术依赖于.NET的“任何 CPU”可执行文件,即使从32位进程调用,也将作为64位进程运行。我们将执行以下步骤:
1.编译一个简短的C#程序,该程序将启动Powershell(即非常简单的“fork”实现 :-))
2.运行已编译的C#程序
3.已编译的C#程序将启动Powershell,但因为它是“Any CPU”,所以将作为64位进程运行,因此它将启动64位Powershell(请注意,因为这只是概念验证,我希望Powershell在您的'path'中)
4.新的64位Powershell将运行我们选择的命令
这是上述操作的屏幕截图(请注意进程的位数):
Process tree http://img3.imageshack.us/img3/3248/powershellfork.png
以下程序期望所有列出的文件驻留在同一目录中。我建议创建一个测试目录,例如C:\Temp\PowershellTest,并将所有文件存储在那里。
程序的入口点将是一个简单的命令。
$basePath = Split-Path -resolve $myInvocation.MyCommand.Path
$exe = Join-Path $basePath test.exe
&"$env:SystemRoot\Microsoft.NET\Framework\v3.5\csc.exe" /nologo /target:exe /out:$exe (Join-Path $basePath test.cs)
&$exe (Join-Path $basePath visibility.ps1)
我会运行csc(32位,但这并不重要:-)),然后运行csc编译器的结果,传递一个参数,即visibility.ps1的完整路径(这是我们想要在64位Powershell中运行的命令)。
C#代码也非常简单:
using System.Diagnostics;
static class Program {
static int Main(string[] args) {
ProcessStartInfo i = new ProcessStartInfo("powershell", args[0]);
i.UseShellExecute = false;
using(Process p = Process.Start(i)) {
p.WaitForExit();
return p.ExitCode;
}
}
}
最后,你的“visibility”脚本:
# file "visibility.ps1"
(dir HKLM:\SOFTWARE).count - (dir HKLM:\SOFTWARE\wow6432node).count
现在从32位PowerShell运行入口脚本可以产生期望的结果(仅为展示我没有作弊,我首先直接运行可见性脚本,然后使用我们的分支技术):
程序运行 http://img3.imageshack.us/img3/2766/powershellrunc.png
Get-Item
或者Get-ChildItem
,但至少它能正常工作。 - jpmc26[Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', 'Registry64').OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock').GetValue('AllowAllTrustedApps')
- zett42