この広告は、90日以上更新していないブログに表示しています。
昔書いたPHPやC#でActive Directoryを検索するサンプルの記事も定期的に検索流入があるんですよね~ということで、今回はC#製アプリをPowerShellから呼び出してみる記事です。
Mjcrosoft製のコマンドラインインターフェースとスクリプト言語からなる仕組みです。UNIX/Linuxのシェルのような感覚でコマンドを打って使うことができ、コマンドプロンプトよりも高度な処理が行えます。
*.ps1のテキストファイルのスクリプトにコマンド群を揃えて実行もでき、変数や条件分岐や繰り返しなど各種プログラム言語と同じようなこともでき、極めるとこれはこれでWindows上での作業を様々に自動化できます。
コマンド(正式にはコマンドレットという)が大文字始まりだったりエラー表示がかなり分かりにくかったりWindows独特なところもあるのですが、Windows7から標準搭載、Windows10ではバージョン5まで進化しました。
なぜか(というと失礼ですが/笑)、AWS
のLambda
関数で使える7言語にもJava, Go, Node.js(JavaScript), C#, Python, Ruby
と並んで入っています。
このPowerShell、Windowsのサービスを呼べたりC#のクラスが使えたり、なかなか奥が深いです。メモ帳を起動したりもできます。ちょいと機会があって調べたので、C#製の自作アプリケーションを起動して出力を得る方法をまとめようと思います。
以下、C#のコンソールアプリケーションは対象のフレームワーク:.NET Core 3.1
で確認していますが、その前の.NET Framework 4.7.*
などでも同じです。
OnitadaSample.exe
を実行する同名のソリューション/プロジェクトを作り、最初に起動されるスタートアップオブジェクトはいつのものProgram
クラスにします。
Environment.Exit({数値});
にしていますがメソッドの戻り値でもOKです。0
、異常が0以外
にするのが伝統ですので、ここでは正常が0、異常が1にしています。Console.WriteLine
して標準出力を渡しています。case
とbreak;
で1行消費しなくてよくなるんですね。C#でもこれやラムダ式で=>
を書いたり、JavaScriptやPHPみたいです。どんどん進化していますね……using System;namespace OnitadaSample{///<summary>/// PowerShellから起動されるサンプルアプリの処理スタートのクラス。///</summary>publicclass Program {staticvoid Main(string[] args) {// PowerShellから呼ぶと引数の配列が正常に渡せない場合があるので、// 念のためひとつの引数に結合して渡しています。string[] argsArray = args[0].Split(',');// 引数0番目:文字列string arg0 = argsArray[0];// 引数1番目:真偽値の文字列string arg1 = argsArray[1].ToLower();if (String.IsNullOrEmpty(arg0) || String.IsNullOrEmpty(arg1)) { Console.WriteLine("引数不正!"); Environment.Exit(1);// Mainメソッドの戻り値をvoidからintに変更、戻り値で示してもOK// return 1; }// リファクタリングすると C# 8.0 の switch 式に変換! (普通のswitch文でもok)string onitadaMsg = arg1switch {"true" =>"引数2は真で鬼のように正しい。つまり、おにただ!","false" =>"引数2は偽。", _ =>"引数2は想定外。", }; Console.WriteLine("引数1: " + arg0 +" " + onitadaMsg); Environment.Exit(0);// Mainメソッドの戻り値をvoidからintに変更、戻り値で示してもOK// return 0; } }}
Windows10 に搭載されているPowerShell バージョン 5.1で動作確認しています。
OnitataSample.exe
の場所をフルパスで指定します。Process
クラスが、以下のような単純なコードでも各種外部アプリケーションを起動できるクラス。System.Diagnostics.Process p = System.Diagnostics.Process.Start("C:\\test.txt");
ProcessStartInfo
クラスも併用する方法をPowerShell上で書くことで、C#のアプリを実行しその終了を待つことができます。onitada.ps1
ファイルの例にあるように、外部アプリケーションの標準出力ストリームと終了コードを得ることができます。# -------------------------------------------------------------------------------------------------------# おにただアプリの呼び出しスクリプトサンプル# 実行方法 ./{このファイル} {第1引数:任意の文字列} {第2引数:"true"/"false"の文字列}# sample > ./onitada.ps1 jaku-chara false# sample > ./onitada.ps1 kyou-chara true# -------------------------------------------------------------------------------------------------------$type =$Args[0]$onitada =$Args[1]# PowerShellからだと正常に渡せないことがあるので、安全のためひとつの# 文字列として渡しています。$serivceArg =$type +"," +$onitada# C#のSystem.Diagnostics.ProcessStartInfoが、# プロセスを起動するときに使用する値のセットです。$pinfo =New-Object System.Diagnostics.ProcessStartInfo# 実行するexeファイルはフルパスでないと動かないです。パスに日本語が# 含まれている場合には、スクリプト自体を# UTF-8+BOM付 もしくは Shift-JIS で保存する必要があります$pinfo.FileName ="D:\OnitadaSample\bin\Debug\netcoreapp3.1\OnitadaSample.exe"$pinfo.RedirectStandardError =$true$pinfo.RedirectStandardOutput =$true$pinfo.UseShellExecute =$false$pinfo.Arguments =$serivceArg# C#のSystem.Diagnostics.Processクラスが、# 外部アプリケーションを実行できるクラス。# 先ほどのProcessStartInfoを引数にして処理をスタートします。# exeを直接実行するのでなくこの方式をとると、# 実行時の標準出力やエラーコードを取得できます。$p =New-Object System.Diagnostics.Process$p.StartInfo =$pinfo$p.Start() |Out-Null$p.WaitForExit()# このクラスのStandardOutputプロパティが、外部アプリケーションの# 標準出力ストリームを読みとってくれるので出力。# 終了コードもExitCodeプロパティで取得できます。$stReader =$p.StandardOutput$strOutput =$stReader.ReadToEnd() +$p.ExitCodeWrite-Host$strOutput
PowerShellウィンドウでコマンドからonitada.ps1
を実行すると以下のようになります。実行のため、最初にポリシー変更が必要です。
S D:\OnitadaSample>Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -ScopeProcess実行ポリシーの変更実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policiesのヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?[Y] はい(Y)[A] すべて続行(A)[N] いいえ(N)[L] すべて無視(L)[S] 中断(S) [?] ヘルプ (既定値は"N"): YPS D:\OnitadaSample> .\onitada.ps1引数不正!1PS D:\OnitadaSample> .\onitada.ps1jaku-chara false引数1:jaku-chara 引数2は偽。0PS D:\OnitadaSample> .\onitada.ps1kyou-chara true引数1:kyou-chara 引数2は真で鬼のように正しい。つまり、おにただ!0PS D:\OnitadaSample>
C#側の標準出力を標準出力ストリームとして受け取り、メソッドの戻り値/終了コードも受け取れることが確認できました。この方式でバッチ処理などなどを実行すると、別のプログラムや別の仕組みに結果を渡して制御することができます。
これで毎週ノルマで定期的に、おにただ! (言ってみたかっただけ...)
Webアプリケーション関連だと言語の選択肢が多いためかいまいちユーザーサイド発の情報が少ない感じのあるC#ですが、ゲーム開発ではUnityに使われたり、Windows自体に高度なアクセスをしようとするとやはりC#の出番になったりします。最近の入門本では以下のあたりでしょうか。
引退した元TRPGゲーマー。COBOLでもなくPL/Iの金融系レガシー紙駆動開発から脱出→国産メーカー系総合ITベンダーのITエンジニア。所謂SIerのSEだけど仕事はほぼソフトウェアエンジニア/ソフトウェアアーキテクトとして、Web開発でコードを書いたり技術を追ったり時々イベントに行ったり、楽しいエンジニアリングを目指しています。Views are my own.
お気軽にどうぞ~
リンク集:https://lit.link/iwasiman
AIイラスト関連の活動はこちら↓
https://www.chichi-pui.com/users/iwasiman/
https://pixiv.me/iwasiman
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。