やること
Powershellを使えば、C#をそのまま実行したりexeファイルを作成することができる。
この機能により、Powershellだけだと難しい複雑な処理もC#で記述して実行することができる。
C#を実行
PowershellにC#のプログラムを文字列で渡し、実行する。
$code = @"
using System;
using System.IO;
using System.IO.Pipes;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
public static class Test {
private static int numThreads = 1;
public static void Main(string[] args) {
Console.WriteLine("NamedPipe Test (s: server, c: client)");
var sorc = Console.ReadLine();
if(sorc == "c") {
CreateClientTask("pipe1").Wait();
}
if(sorc == "s") {
CreatePipeServerTask("pipe1").Wait();
}
}
public static Task CreatePipeServerTask(string pipeName) {
return Task.Run(() => {
NamedPipeServerStream pipeServer = null;
while(true) {
try {
pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads);
pipeServer.WaitForConnection();
StreamString ss = new StreamString(pipeServer);
while (true)
{
var read = ss.ReadString();
var write = ss.WriteString("Server read OK.");
Console.WriteLine("Read Data = " + read);
if (read == "end") break;
}
}
catch(OverflowException ofex) {
Console.WriteLine(ofex.Message);
}
finally {
pipeServer.Close();
}
}
});
}
public static Task CreateClientTask(string pipeName){
return Task.Run(() => {
while (true) {
NamedPipeClientStream pipeClient = null;
try {
pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation);
pipeClient.Connect();
var ss = new StreamString(pipeClient);
while (true) {
var writeData = Console.ReadLine();
var write = ss.WriteString(writeData);
var read = ss.ReadString();
Console.WriteLine("Server Response = " + read);
if (writeData == "end") break;
}
}
catch (OverflowException ofex) {
Console.WriteLine(ofex.Message);
}
catch (IOException ioe) {
Console.WriteLine(ioe.Message);
}
finally {
pipeClient.Close();
}
}
});
}
}
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
int len = 0;
len = ioStream.ReadByte() * 256;
len += ioStream.ReadByte();
byte[] inBuffer = new byte[len];
ioStream.Read(inBuffer, 0, len);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
int len = outBuffer.Length;
if (len > UInt16.MaxValue)
{
len = (int)UInt16.MaxValue;
}
ioStream.WriteByte((byte)(len / 256));
ioStream.WriteByte((byte)(len & 255));
ioStream.Write(outBuffer, 0, len);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
"@
Add-Type -TypeDefinition $code -Language CSharp
[Test]::Main("")
C#をコンパイルした実行ファイルを作成
C#からPowershellでexeを作成。
$exeName = "test.exe"
$exeFullPath = ($PSScriptRoot + "\" + $exeName)
$code = @"
using System;
using System.IO;
using System.IO.Pipes;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
public static class Test {
private static int numThreads = 1;
public static void Main(string[] args) {
Console.WriteLine("NamedPipe Test (s: server, c: client)");
var sorc = Console.ReadLine();
if(sorc == "c") {
CreateClientTask("pipe1").Wait();
}
if(sorc == "s") {
CreatePipeServerTask("pipe1").Wait();
}
}
public static Task CreatePipeServerTask(string pipeName) {
return Task.Run(() => {
NamedPipeServerStream pipeServer = null;
while(true) {
try {
pipeServer = new NamedPipeServerStream(pipeName, PipeDirection.InOut, numThreads);
pipeServer.WaitForConnection();
StreamString ss = new StreamString(pipeServer);
while (true)
{
var read = ss.ReadString();
var write = ss.WriteString("Server read OK.");
Console.WriteLine("Read Data = " + read);
if (read == "end") break;
}
}
catch(OverflowException ofex) {
Console.WriteLine(ofex.Message);
}
finally {
pipeServer.Close();
}
}
});
}
public static Task CreateClientTask(string pipeName){
return Task.Run(() => {
while (true) {
NamedPipeClientStream pipeClient = null;
try {
pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation);
pipeClient.Connect();
var ss = new StreamString(pipeClient);
while (true) {
var writeData = Console.ReadLine();
var write = ss.WriteString(writeData);
var read = ss.ReadString();
Console.WriteLine("Server Response = " + read);
if (writeData == "end") break;
}
}
catch (OverflowException ofex) {
Console.WriteLine(ofex.Message);
}
catch (IOException ioe) {
Console.WriteLine(ioe.Message);
}
finally {
pipeClient.Close();
}
}
});
}
}
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
int len = 0;
len = ioStream.ReadByte() * 256;
len += ioStream.ReadByte();
byte[] inBuffer = new byte[len];
ioStream.Read(inBuffer, 0, len);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
int len = outBuffer.Length;
if (len > UInt16.MaxValue)
{
len = (int)UInt16.MaxValue;
}
ioStream.WriteByte((byte)(len / 256));
ioStream.WriteByte((byte)(len & 255));
ioStream.Write(outBuffer, 0, len);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
"@
Add-Type -TypeDefinition $code -Language CSharp -OutputAssembly $exeFullPath -OutputType ConsoleApplication