前提・実現したいこと
一つのバッチファイルに、C#コードを埋め込んでおいて、
実行したときに「コンパイル→成果物を実行」のようなことができないか、調べています。
手法の名前が分からず、調査が難航しており、
そもそも、実現可能かどうかも分からなかった為、質問することにしました。
JScript.NET という言語向けには、下記のような実装があるので、
これと同じことをC#でも、できないか知りたいです。
bat
1@if(0)==(0) echo off&title %~n0&for /f "tokens=*" %%i in ('certutil -hashfile "%~f0" ^| find /v ":"') do (set app_hash=%%i) 2set app_path=%~dp0%~n0[%app_hash%].exe 3if not exist "%app_path%" ( 4 del "%~dp0%~n0[*].exe">nul 2>&1&setlocal enabledelayedexpansion&for /f "tokens=*" %%i in ('where /r %windir%\Microsoft.NET jsc.exe ^| sort') do (set compiler_path=%%i) 5 "!compiler_path!" /nologo /out:"%app_path%" "%~f0" 6) 7"%app_path%" %*&exit /b %errorlevel% 8@end 9 10//! @file template.bat 11//! @version 1.00r1 12 13import System; 14import System.Threading; 15import System.Reflection; 16import System.IO; 17 18// エントリーポイント 19Environment.Exit(function(){ 20 Console.WriteLine("Hello JScript.NET!!"); 21 Console.ReadKey(); 22 return 0; 23}());
上記のバッチファイルが、どういった仕組みで動作しているのかは、
全貌を理解できていませんが実行すると、下記のような挙動になります。
- @end 以下に書いたソースコードがコンパイルされて実行される
- ソースコードに変更を加えない場合は、コンパイルがスキップされる
- 更新があったときは、古い成果物が削除されてから実行される
発生している問題
分からないなりに格闘して、現状は下記の形になっています。
bat
1/* 2@echo off&title %~n0 3for /f "tokens=*" %%i in ('certutil -hashfile "%~f0" ^| find /v ":"') do (set app_hash=%%i) 4set app_path=%~dp0%~n0[%app_hash%].exe 5if not exist "%app_path%" ( 6 del "%~dp0%~n0[*].exe">nul 2>&1 7 setlocal enabledelayedexpansion&for /f "tokens=*" %%i in ('where /r %windir%\Microsoft.NET csc.exe ^| sort') do (set compiler_path=%%i) 8 "!compiler_path!" /nologo /out:"%app_path%" "%~f0" 9) 10"%app_path%" %*&exit /b %errorlevel% 11*/ 12 13//! @file template.bat 14//! @version 1.00r1 15 16using System; 17 18class Program 19{ 20 static void Main(string[] args) 21 { 22 Console.WriteLine("Hello C# !!"); 23 Console.ReadKey(); 24 } 25}
これを実行した場合は、エラーが出ます。
'/*' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 Hello C# !!
補足情報(FW/ツールのバージョンなど)
環境は、Windows10 Pro 64bit です。
よろしくお願いします。
まとめ(追記)
最終的なコードです。
@echo off&title %~n0&setlocal enabledelayedexpansion&for /f "tokens=*" %%i in ('certutil -hashfile "%~f0"^|find /v":"') do (set app_hash=%%i) set app_name=%~dp0%~n0[%app_hash%]&set src_path=!app_name!.cs if not exist "%app_name%.exe" (del "%~dp0%~n0[*].*">nul 2>&1&type "%~f0"|more +5>"%src_path%"&for /f "tokens=*" %%i in ('where /r %windir%\Microsoft.NET csc.exe^|sort') do (set compiler_path=%%i) "!compiler_path!" /nologo /out:"%app_name%.exe" "%src_path%") "%app_name%.exe" %*&exit /b %errorlevel% //! @file template.bat //! @version 1.00r1 using System; class Program { static void Main(string[] args) { Console.WriteLine("Hello C# !!"); Console.ReadKey(); } }
回答2件
あなたの回答
tips
プレビュー