如何从32位Powershell实例访问64位注册表? [英] How to access the 64-bit registry from a 32-bit Powershell instance?

查看:172
本文介绍了如何从32位Powershell实例访问64位注册表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果启动Powershell的32位实例(%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe),则注册表提供程序仅会看到注册表中有限的32位部分

If you launch a 32-bit instance of Powershell (%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe), then the registry provider only sees the limited 32-bit parts of the registry.

**32-bit console**
PS> (dir HKLM:\SOFTWARE | measure).count - (dir HKLM:\SOFTWARE\wow6432node | measure).count

0

**64-bit console**
PS> (dir HKLM:\SOFTWARE | measure).count - (dir HKLM:\SOFTWARE\wow6432node | measure).count

-5

是否有任何方法可以强制提供程序进入64位模式?我可以使用[Microsoft.Win32] .Net API或WMI,但我不想这样做。如果使用Powershell v2 CTP3可以扩展所有功能,则可以使用。

Is there any way to force the provider into 64-bit mode? I could drop down to [Microsoft.Win32] .Net APIs, or maybe WMI, but I'd rather not. I'm using Powershell v2 CTP3 if that expands the possibilities at all.

推荐答案

当Powershell以32位进程运行时,我不知道将其切换到64位模式的机制。 64位系统中虚拟化支持的全部要点是使32位进程相信它们生活在32位OS中。

When Powershell is running as a 32 bit process, I am not aware of a mechanism to "switch it" to 64bit mode. The whole point of virtualization support in 64bit systems is to make 32bit processes believe they are living in a 32bit OS...

但是,那是说我在过去,它对我来说非常不错(以下代码已在带有Powershell v1的Vista SP1 x64上进行了测试)。该技术依赖于这样一个事实:即使从32位进程中调用,.NET的 Any CPU可执行文件也将以64位进程运行。我们将执行的步骤:

However, that said I used the following technique in the past and it worked very nicely for me (the following code was tested on Vista SP1 x64 with Powershell v1). The technique relies on the fact that .NET's "Any CPU" executables will run as 64bit process even when invoked from a 32bit process. The steps we will be performing:


  1. 编译一个简短的C#程序,它将启动powershell(即非常简单的 fork实现:-) )

  2. 运行已编译的C#程序

  3. 已编译的C#程序将启动Powershell,但由于它是任何CPU,因此它将作为64位进程,因此它将启动64位Powershell(请注意,因为这只是概念验证,我希望Powershell处于您的路径中)

  4. 新的64位Powershell将运行我们选择的命令行开关

  1. Compile a short C# program that will start powershell (i.e. a very simple "fork" implementation :-) )
  2. Run the compiled C# program
  3. The compiled C# program will start Powershell, but because it's "Any CPU", it will be running as a 64bit process so it will start 64bit Powershell (note that because this is just a proof-of-concept, I expect powershell to be in your 'path')
  4. The new 64bit Powershell will run a commandlet of our choice

这是上面操作的屏幕截图(注意过程的位):
进程树http://img3.imageshack.us/img3/3248/powershellfork.png

This is a screenshot of the above in action (notice bit-ness of the processes): Process tree http://img3.imageshack.us/img3/3248/powershellfork.png

以下程序希望列出的所有文件都位于同一目录中。我建议创建一个测试目录,例如C:\Temp\PowershellTest,并将所有文件存储在那里)。

The following program expects all the files listed to reside in the same directory. I recommend creating a test directory, e.g. C:\Temp\PowershellTest, and storing all the files there).

指向该程序的入口将是一个简单的命令行开关:

Entry point to the program will be a simple commandlet:

# 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编译器的结果,并传递一个参数(能见度的完整路径)。ps1(这是我们要运行的Commandlet在64位Powershell中)。

It runs csc (32bit, but it doesn't matter :-) ) and then runs result of csc compiler, passing one argument, (full path to) visibility.ps1 (this is the commandlet we want to run in 64bit Powershell).

C#代码也非常简单:

The C# code is very simple as well:

// 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运行输入脚本所需的结果(只是为了表明我没有作弊,我先直接运行了可见性脚本,然后使用我们的fork技术):

Running the entry script from 32bit Powershell now yields desired result (just to show I was not cheating I run the visibility script directly first, then using our fork technique):

程序运行http://img3.imageshack.us/img3/2766/powershellrunc.png

这篇关于如何从32位Powershell实例访问64位注册表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆