Когда Powershell работает как 32-битный процесс, я не знаю механизма «переключения» в 64-битный режим. Весь смысл поддержки виртуализации в 64-битных системах состоит в том, чтобы заставить 32-битные процессы полагать, что они живут в 32-битной ОС ...
Однако это говорит о том, что я использовал следующую технику в прошлом, и она очень хорошо работала для меня (следующий код был протестирован на Vista SP1 x64 с Powershell v1). Этот метод основан на том факте, что исполняемые файлы .NET «Любой ЦП» будут работать как 64-битный процесс, даже если он вызывается из 32-битного процесса. Шаги, которые мы будем выполнять:
- Скомпилируйте короткую C # -программу, которая запустит PowerShell (т.е. очень простая реализация "fork" :-))
- Запустите скомпилированную программу C #
- Скомпилированная программа C # запустит Powershell, но, поскольку это «Любой ЦП», он будет работать как 64-битный процесс, поэтому он запустит 64-битный Powershell (обратите внимание, что, поскольку это всего лишь подтверждение концепции, я ожидаю powershell быть на твоем «пути»)
- Новый 64-битный Powershell будет запускать выбранный нами командлет
Это скриншот выше в действии (обратите внимание на битность процессов):
Дерево процессов http://img3.imageshack.us/img3/3248/powershellfork.png
Следующая программа ожидает, что все перечисленные файлы будут находиться в одном каталоге. Я рекомендую создать тестовый каталог, например, C: \ Temp \ PowershellTest и сохраняя там все файлы).
Точкой входа в программу будет простой командлет:
# file "test.ps1"
$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 # также очень прост:
// file "test.cs"
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;
}
}
}
И, наконец, ваш сценарий «видимости»:
# file "visibility.ps1"
(dir HKLM:\SOFTWARE).count - (dir HKLM:\SOFTWARE\wow6432node).count
Запуск сценария ввода из 32-битного Powershell теперь дает желаемый результат (просто чтобы показать, что я не обманывал, сначала запускаю сценарий видимости, а затем используем нашу технику форка):
Запуск программы http://img3.imageshack.us/img3/2766/powershellrunc.png