C#メモ PowerShellのps1ファイルにC#のコードを埋め込んで実行してみる

C#

WSH(Windows Script Host)なVBScriptやJScriptでもいいんだけど…せっかくなんで最近の仕組みを使いたくなって…。
んで、ネットに聞いてみたらPowerShellがなかなか使えるぞってのがわかったから試すことに。

ポイントとしてはこんな感じ。

  • PowerShellのスクリプトファイルを作成する
    ※スクリプトファイルの中にC#のコードを埋め込む
  • コマンドプロンプトからPowerShellをファイル指定で実行する

今回書いてみたph1ファイルの内容はこんな感じ。

# C#のコードを記述する
$source = @"
public static class Proto
{
	public static void Function()
	{
		System.Console.WriteLine("Call!!");
	}
}
"@

# C#のコードをビルドする
Add-Type -TypeDefinition $source -Language CSharp

# 指定したクラスのメソッドを呼び出す
[Proto]::Function()

コマンドプロンプトから実行するときのコマンドラインはこんな感じ。

powershell -ExecutionPolicy RemoteSigned -File Proto.ps1

ここで、Set-ExecutationPolicyは管理者権限でPowerShellを実行するときは要らないけど、ユーザ権限で実行するときはこんなエラーメッセージが表示されて実行できない。

.\Proto.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Users\tetsuyanbo\Desktop\Sample\Proto.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(http://go.microsoft.com/fwlink/?LinkID=135170) を参照してくださ
い。
発生場所 行:1 文字:1
+ .\Proto.ps1
+ ~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

で、実行するとこんな感じ。
ちゃんとC#のコードで書いた文字列が表示されとる。

いいところはこんなところ。

  • コードの修正がすぐできる
  • Windows7以降だったらPowerShellとC#のコンパイラが標準装備だから何かインストールする必要がない

あかんところはこんなところ。

  • 実行にはセキュリティの壁がある
  • C#のコードに未使用の変数があるとかVisual Studioでは見逃してくれるビルドの警告はエラーになって実行できない

たとえば、今回のサンプルコードで変数nValueってのを宣言しただけだとVisual Studioでは警告で見逃してくれるんだけど、PowerShellではこんなメッセージが表示される。

Add-Type : c:\Users\tetsuyanbo\AppData\Local\Temp\yqqziibh.0.cs(5) : エラーとしての警告: 変数 'nValue' は宣言されていま
すが、使用されませんでした。
c:\Users\tetsuyanbo\AppData\Local\Temp\yqqziibh.0.cs(4) : 	{
c:\Users\tetsuyanbo\AppData\Local\Temp\yqqziibh.0.cs(5) : >>> 		int nValue;
c:\Users\tetsuyanbo\AppData\Local\Temp\yqqziibh.0.cs(6) : 		System.Console.WriteLine("Call!!");
発生場所 C:\Users\tetsuyanbo\Desktop\Sample\Proto.ps1:14 文字:1
+ Add-Type -TypeDefinition $source -Language CSharp
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (Microsoft.Power...peCompilerError:AddTypeCompilerError) [Add-Type]、Excepti
    on
    + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands.AddTypeCommand
 
Add-Type : 型を追加できません。コンパイル エラーが発生しました。
発生場所 C:\Users\tetsuyanbo\Desktop\Sample\Proto.ps1:14 文字:1
+ Add-Type -TypeDefinition $source -Language CSharp
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Add-Type]、InvalidOperationException
    + FullyQualifiedErrorId : COMPILER_ERRORS,Microsoft.PowerShell.Commands.AddTypeCommand
 
型 [Proto] が見つかりません。
発生場所 C:\Users\tetsuyanbo\Desktop\Sample\Proto.ps1:15 文字:1
+ [Proto]::Function()
+ ~~~~~~~
    + CategoryInfo          : InvalidOperation: (Proto:TypeName) []、RuntimeException
    + FullyQualifiedErrorId : TypeNotFound
 

んまま、明日への自分へのメモってことで。