0%

动态编译生成CLI软件启动器

从Linux换到Windows之后 手总是忍不住Ctrl Alt T

后来设置了打开Terminal的快捷键 但是还是不顺心

Windows的命令行 什么都干不了

情境

本人想要用命令行启动一切

但是如果把所有软件的目录都添加到PATH 就会让PATH无比混乱

于是在新建了一个C:\PathApp\ 并且添加到PATH

然后想把软件的快捷方式 放进去

失败了 并不能启动 PATH中的快捷方式

解决方案

实现启动器

尝试写一个程序 作为启动器 比如我要启动cmd.exe

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Diagnostics;

namespace Launcher
{
class MainClass
{
static void Main()
{
using (Process myProcess = new Process())
{
myProcess.StartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "cmd.exe";
myProcess.Start();
}
}
}
}

可是这样的话 我没法传参数

于是

1
2
3
4
5
6
7
8
9
10
static void Main(string[] args)
...
string argString = "";
foreach(var Arg in args)
{
argString += Arg;
}
...
myProcess.StartInfo.Arguments = argString;
...

实现启动器生成器

这里需要用到一个好东西 动态编译

能让你调用C#的编译器 把程序内的文本代码编译成C#程序集并输出exe

1
2
3
4
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
//别跟我说CodeDom已经过时了 我TM当然知道他过时了 Roslyn微软的文档写的不明不白 鬼知道怎么用 CodeDom真香

然后用户给出两个String

1
2
3
4
Console.Write("ApplicationName > ");
var filename = Console.ReadLine();
Console.Write("OutputName > ");
var oname = Console.ReadLine();

然后把代码拼好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
string code = @"using System.Diagnostics;
class MainClass
{
static void Main(string[] args)
{
string argString = """";
foreach(var Arg in args)
{
argString += Arg;
}
using (Process myProcess = new Process())
{
myProcess.StartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.Arguments = argString;
myProcess.StartInfo.FileName = """ + filename.Replace("\\", "\\\\") + @""";
myProcess.Start();
}
}
}
";

一顿操作 动态编译

1
2
3
4
5
6
7
8
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameter = new CompilerParameters();

parameter.ReferencedAssemblies.Add("System.dll");

parameter.GenerateExecutable = true;
parameter.OutputAssembly = "C:\\PathApp\\" + oname + ".exe";
var results = provider.CompileAssemblyFromSource(parameter, code);

如果编译没成功 出错了咋办?

1
2
3
4
5
if (results.Errors.HasErrors)
{
Console.WriteLine(results.Errors[0].ToString());
Console.ReadKey();
}

生成 把该文件放到C:\PathApp\

使用示例

pic1

成品

Github仓库: https://github.com/F-Unction/CLILauncherGenerator 求Star