배치 파일에 C# 코드 포함 실행
5697 단어 Windows.NETPowerShellBatchfileC#
코드
RunCSCode.bat@echo off
setlocal
set BAT_PATH=%~f0
powershell -NoProfile -Command "& {$cscode=[regex]::Split([IO.File]::ReadAllText($env:BAT_PATH,[Text.Encoding]::UTF8),':EndBatch')[2]; Add-Type -TypeDefinition $cscode -Language CSharpVersion3; [CSBatch.Program]::Main($Args);}" %*
endlocal
exit /b
:EndBatch
//CSCode
using System;
using System.Runtime.InteropServices;
namespace CSBatch
{
public class Program
{
[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern int MessageBox(IntPtr hWnd, string text, string caption, int options);
public static int Main(string[] args)
{
string msg = "";
for( int i=0; i<args.Length; i++)
{
msg += String.Format("args[{0}]={1}\r\n", i, args[i]);
}
if( msg=="" )
{
msg = "no args.";
}
int MB_OK = 0;
MessageBox(IntPtr.Zero, msg, "CSTestCode", MB_OK);
return args.Length;
}
}
}
실행 결과
>RunCSCode.bat あああ いいい ううう
3
작동 원리
1. 일반 배치 파일로 시작
2. 환경 변수에 배치 파일 자신의 경로를 저장 (직접 powershell 명령에 임베드해도 좋을지도)
3. (powershell 명령) 배치 파일 자체를 File.ReadAllText에서 utf-8 string 데이터로로드
4. (powershell 명령) Regex.Split을 사용하여 string 데이터를 :EndBatch 레이블로 분할하고 C# 코드 부분을 분리
5. (powershell 명령) 분리 된 C# 코드 부분을 Add-Type으로 형식 추가하고 C# 메서드를 실행
6. powershell에서 C# 메소드 실행 종료 후 exit/b 로 배치 파일 종료.
(이것에 의해, 이후의 C# 코드부의 영향을 받지 않게 된다)
주의) 배치 파일을 읽을 때 utf-8 인코딩을 지정했지만 BOM 없이 utf-8로 배치 파일을 저장하지 않으면 런타임에 쓰레기가 붙습니다.
MessageBox.Show가 아니라 WinAPI의 MessageBox 사용하고 있는 것은, WinAPI도 호출할 수 있다고 하는 것을 보여주고 싶었을 뿐입니다. 음 C#이므로 할 수 있어 당연합니다만…
뭔가 여러가지 재미있는 일(위험한 일이라고도 함) 할 수 있을 것 같네요.
참고 기사
배치 파일에 C# 코드 작성
배치 파일에서 ps1 파일에 작성한 C# 코드를 호출하여 만족한 후 이 기사를 보고 눈에서 비늘이 떨어졌습니다.
Reference
이 문제에 관하여(배치 파일에 C# 코드 포함 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/radian-jp/items/8a8037e2f0d178b013cd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
@echo off
setlocal
set BAT_PATH=%~f0
powershell -NoProfile -Command "& {$cscode=[regex]::Split([IO.File]::ReadAllText($env:BAT_PATH,[Text.Encoding]::UTF8),':EndBatch')[2]; Add-Type -TypeDefinition $cscode -Language CSharpVersion3; [CSBatch.Program]::Main($Args);}" %*
endlocal
exit /b
:EndBatch
//CSCode
using System;
using System.Runtime.InteropServices;
namespace CSBatch
{
public class Program
{
[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern int MessageBox(IntPtr hWnd, string text, string caption, int options);
public static int Main(string[] args)
{
string msg = "";
for( int i=0; i<args.Length; i++)
{
msg += String.Format("args[{0}]={1}\r\n", i, args[i]);
}
if( msg=="" )
{
msg = "no args.";
}
int MB_OK = 0;
MessageBox(IntPtr.Zero, msg, "CSTestCode", MB_OK);
return args.Length;
}
}
}
>RunCSCode.bat あああ いいい ううう
3
작동 원리
1. 일반 배치 파일로 시작
2. 환경 변수에 배치 파일 자신의 경로를 저장 (직접 powershell 명령에 임베드해도 좋을지도)
3. (powershell 명령) 배치 파일 자체를 File.ReadAllText에서 utf-8 string 데이터로로드
4. (powershell 명령) Regex.Split을 사용하여 string 데이터를 :EndBatch 레이블로 분할하고 C# 코드 부분을 분리
5. (powershell 명령) 분리 된 C# 코드 부분을 Add-Type으로 형식 추가하고 C# 메서드를 실행
6. powershell에서 C# 메소드 실행 종료 후 exit/b 로 배치 파일 종료.
(이것에 의해, 이후의 C# 코드부의 영향을 받지 않게 된다)
주의) 배치 파일을 읽을 때 utf-8 인코딩을 지정했지만 BOM 없이 utf-8로 배치 파일을 저장하지 않으면 런타임에 쓰레기가 붙습니다.
MessageBox.Show가 아니라 WinAPI의 MessageBox 사용하고 있는 것은, WinAPI도 호출할 수 있다고 하는 것을 보여주고 싶었을 뿐입니다. 음 C#이므로 할 수 있어 당연합니다만…
뭔가 여러가지 재미있는 일(위험한 일이라고도 함) 할 수 있을 것 같네요.
참고 기사
배치 파일에 C# 코드 작성
배치 파일에서 ps1 파일에 작성한 C# 코드를 호출하여 만족한 후 이 기사를 보고 눈에서 비늘이 떨어졌습니다.
Reference
이 문제에 관하여(배치 파일에 C# 코드 포함 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/radian-jp/items/8a8037e2f0d178b013cd
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
배치 파일에 C# 코드 작성
배치 파일에서 ps1 파일에 작성한 C# 코드를 호출하여 만족한 후 이 기사를 보고 눈에서 비늘이 떨어졌습니다.
Reference
이 문제에 관하여(배치 파일에 C# 코드 포함 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/radian-jp/items/8a8037e2f0d178b013cd텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)