2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PowershellでC#を実行、exeファイルを作成

Posted at

やること

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

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?