I'm trying to build a module in C# for Powershell 2.0 on a machine where I don't have administrator permissions and no tools installed explicitly for building. I've got almost everything I think I'd need to make this work, but I'm botching the csc
call somehow.
PS C:\temp\> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
2 0 -1 -1
To get the System.Management.Automation dll
out of the CAC, I followed this brilliant advice:
Copy ([PSObject].Assembly.Location) C:\temp
To build with csc
, I'm trying to follow this advice from Mr. Skeet:
In addition to this, you can use /noconfig /nostdlib and then explicitly reference the .NET 2.0 assemblies (in c:\Windows\Microsoft.NET\Framework\v2.0.50727 for example). It looks like the /lib command line option can make this slightly easier by letting you specify a directory to look in for references, but I haven't tried that myself.
Here's my current command line:
csc /out:shims.dll /target:library /noconfig /nostdlib /lib:c:\Windows\Microsoft.NET\Framework\v2.0.50727 /r:..\System.Management.Automation.dll;System.dll;mscorlib.dll PowershellPlay.cs
That builds fine, but when I try to import the module, I get that I'm using too new a version of the framework -- which, of course, is what I was trying to avoid with the /lib, /nostdlib, and /noconfig settings.
Import-Module : Could not load file or assembly 'file:///C:\temp\PowerCLI_1\shi
ms.dll' or one of its dependencies. This assembly is built by a runtime newer t
han the currently loaded runtime and cannot be loaded.
At line:1 char:14
+ Import-Module <<<< .\shims.dll
+ CategoryInfo : NotSpecified: (:) [Import-Module], BadImageForma
tException
+ FullyQualifiedErrorId : System.BadImageFormatException,Microsoft.PowerSh
ell.Commands.ImportModuleCommand
Wonder if I have to change which csc I use? Doesn't seem like that should be a requirement/matter.
c:\temp>where csc
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe
EDIT: Okay, I think I've got the answer: I'm doing things in my code that aren't .NET 2.0 kosher. I'm a little surprised the 2.0 version of csc seems to compile it, though. ??
Anyhow, the below works:
Code for cmdlet:
using System;
using System.Management.Automation;
[Cmdlet("Test", "PowershellCompilation")]
public class Test : Cmdlet
{
[Parameter]
public string Server = "";
protected override void ProcessRecord()
{
WriteObject(this.Server + "test");
}
}
csc
call:
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\csc /out:test.dll /target:library /r:..\System.Management.Automation.dll Test.cs
I've got that call in a bat file named buildTest.bat
.
PS C:\temp\PowerCLI_1> .\buildTest.bat
C:\temp\PowerCLI_1>C:\Windows\Microsoft.NET\Framework64\v2.0.50727\csc /out:test
.dll /target:library /r:..\System.Management.Automation.dll Test.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.5483
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.
PS C:\temp\PowerCLI_1> Import-Module .\test.dll
PS C:\temp\PowerCLI_1> Test-PowershellCompilation
test
PS C:\temp\PowerCLI_1> Test-PowershellCompilation -Server spam
spamtest
PS C:\temp\PowerCLI_1>
Note that I was unable to get the 4.0 version of csc
to work using a command like this:
csc /out:test.dll /target:library /noconfig /nostdlib /lib:c:\Windows\Microsoft.NET\Framework\v2.0.50727 /r:..\System.Management.Automation.dll;System.dll;mscorlib.dll Test.cs
That gave the "runtime newer" error again.
So success. I'll try to convince Eris to turn the comment into an answer; if I'd tried the 2.0 version of csc first, I wouldn't've tried the "compile for 2 with csc for 4" madness.