4

In a regular PowerShell window, one can determine if the current shell is x64 or x86 by examining the boolean environment variable [Environment]::Is64BitProcess.

Now I did the same but from an embedded PS session in a .NET application. And the output shows the bitness is not 64bit.

static void Main(string[] args)
{
    using (PowerShell ps = PowerShell.Create())
    {
        foreach (var res in ps
            .AddScript("$host.version.tostring()").AddStatement()
            .AddScript("[Environment]::Is64BitProcess").AddStatement()
            .Invoke())
        {
            Console.WriteLine(res.BaseObject);
        }

        // Outputs:
        // 4.0
        // False
    }
}

Using corflags and ildasm, I made sure the referenced System.Management.Automation DLL is v4.0 and ILONLY. And even if I invoke my application from an x64 shell (e.g., PowerShell.exe x64), the result still indicates Is64BitProcess == false. Any hint?

This is important because I want to Add-PsSnapin from the embedded session. Without getting the bitness right, the SnapIn can't be loaded.

Community
  • 1
  • 1
KFL
  • 17,162
  • 17
  • 65
  • 89
  • If you compile it as a 32-bit application, you're probably being tripped by the [`File System Redirector`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187%28v=vs.85%29.aspx). – Mathias R. Jessen Apr 07 '15 at 15:48
  • @MathiasR.Jessen it's compiled as "Any CPU". But if I go "force" it to be "X64" in the build configuration, it'll work. – KFL Apr 09 '15 at 17:12

3 Answers3

2

OK, just figured it out. In the project properties, If I "force" the build target from Any CPU to X64, it solved the problem. The embedded PS session correctly shows the bitness is 64bit, and all registered snap-ins are correctly listed.

enter image description here

I still don't know why Any CPU won't work. Maybe it's because the Prefer 32-bit checkbox was checked by default for Any CPU option.

KFL
  • 17,162
  • 17
  • 65
  • 89
2

The bitness of the embedded PowerShell session follows the bitness of the .NET process calling it.

There seems to be no way (using System.Management.Automation) to run a 32-bit embedded PowerShell process from a 64-bit parent process or vice versa (although I'm curious if there is one).

If you have no problem with forcing the parent process to 64-bit, and you are wondering why it is running as a 32-bit process, here are possible reasons:

  • The platform is set to "x86"
  • The platform is set to "Any CPU", and "Prefer 32-bit" is checked
  • The platform is set to "Any CPU", and the parent process is a web application running in IIS Express when running from Visual Studio. You can change this in the Visual Studio settings (Tools > Options > project and Solutions > Web Projects > Use the 64 bit version of IIS Express...). Note that, in production (regular IIS, Azure websites, etc.), the parent process will probably run as 64-bit by default.
Pieter
  • 458
  • 5
  • 16
Florian Winter
  • 4,750
  • 1
  • 44
  • 69
1

This is a guess, but you probably used the 32-bit version of the PowerShell assembly in your project references.

Make sure you reference a 64-bit version of the System.Management.Automation.dll assembly.

On a 64-bit Windows installation, you can find the assemblies here:
32-bit version:

C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\[PS version installed]\System.Management.Automation.dll

64-bit version:

C:\Program Files\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • That was what I did. I also mentioned in the original post that with `corflags` I made sure the assembly is `ILONLY`. – KFL Apr 09 '15 at 17:13