Wednesday, March 23, 2005 9:37 PM
jclark
It's Not Monad, but...
I wish that this blog entry was about “Monad”.
“Monad” is a new command shell that Microsoft is working on. The shell is built with managed code and is more featured, by far, then CMD.exe. One feature of Monad that I look forward to is the ability to extend the shell with my own managed code extensions called cmdlets.
But as I said, this blog entry isn’t about Monad. Nope, here I am going to show you a .bat file that you might find useful. I wrote this .bat file (with more then a little help from my friend Geary “I’m batman” Eppley), during a project where I needed a fair amount of cmd scripts, and I was becoming frustrated by the limitations of the batch language. (Batch, amazingly, hasn’t improved much since DOS.) I wanted to use C# as my script language.
On a system with the .NET Framework installed, with a few syntax shenanigans, you can embed arbitrary C# code into a batch file. Then you can write the logic of your script as C#. At the end of this entry is a batch file that creates such C# bat files (using the same technique as its implementation).
What the batch file is doing is creating a temporary file from the subset of the file that contains C# syntax. Then it is searching for the latest version of the .NET Framework on the system, and it is compiling the C# into an executable using the compiler. After that it is running the executable, passing on the bat arguments to the newly created exe. Then the exe returns, as does the .bat. Finally the .bat cleans-up after itself. This is no Monad, but it is a way to use C# for scripting.
Alight, here is a template .bat file for creating C# based .bat scripts.
@echo off & goto :beginScript
#endif
#line 4
/******** Put compilable C# code after this line ********/
using System;
using System.IO;
class App {
public static void Main(String[] args) {
Console.WriteLine("Put whatever logic here you want!");
}
}
/*******************************************************/
#if NO
:beginScript
setlocal
set versions=
:: Uncomment the following line (remove REM) to limit the fx versions. Uses newest by default.
rem SET versions=v1.0.3705 v1.1.4322
set tempCs=%~s0
set tempCs=%tempCs:\=.%
set tempCs=%tempCs::=.%
set tempCs=%TEMP%\%tempCs%
if not exist %tempCs%.exe goto :build
::check for up-to-date .exe
copy %~s0 %tempCs%.tst 1>nul 2>&1
for /F %%i in ('dir /od /b %tempCs%.*') do set latestCs=%%~xi
del %tempCs%.tst 1>nul 2>&1
if "%latestCs%"==".exe" goto :run
:build
if defined versions FOR %%c IN (%versions%) DO IF EXIST %SystemRoot%\Microsoft.Net\Framework\%%c\csc.exe (SET netpath=%SystemRoot%\Microsoft.Net\Framework\%%c)
if not defined versions for /F %%c in ('dir /b /on %SystemRoot%\Microsoft.Net\Framework\v?.*') do if exist %SystemRoot%\Microsoft.Net\Framework\%%c\csc.exe (SET netpath=%SystemRoot%\Microsoft.Net\Framework\%%c)
if not exist %netpath%\csc.exe GOTO noFramework
echo #line 1 "%0" >%tempCs%.cs
echo #if NO >>%tempCs%.cs
TYPE %~s0 >>%tempCs%.cs
%netpath%\csc.exe /out:"%tempCs%.exe" %tempCs%.cs >nul
if ERRORLEVEL 1 goto badCompile
if exist %tempCs%.cs DEL /q %tempCs%.cs
:run
%tempCs%.exe %*
goto :EOF
:badCompile
%netpath%\csc.exe /out:"%tempCs%.exe" %tempCs%.cs
IF EXIST %tempCs%.cs DEL /q %tempCs%.cs
goto :EOF
:noFramework
ECHO ERROR: This batch file requires the .Net framework.
goto :EOF
#endif