oynix

人生需要一些摸鱼时刻,做什么都可以,不做什么也可以

CSharp使用代码在新Terminal窗口执行命令

当通过代码调用其他系统命令或者程序时,需要弹出一个新的终端窗口,并在这个窗口中执行命令,命令执行完成后,这个窗口则会自动关闭。

1. Windows

在Windows中,直接使用Process即可,dotnet对Windows的适配还是可以的,不需要什么额外的操作就可以达到目标效果,

1
2
3
4
5
6
7
8
9
10
11
public static void InvokCommand(string cmd, string args)
{
var proc = new Process();
proc.StartInfo.FileName = cmd;
proc.StartInfo.Arguments = args;
proc.CreateNoWindow = false;
proc.UseShellExecute = true;
proc.Start();
proc.WaitForExit();
proc.Close();
}

其中,FileName是命令的路径,这里需要写绝对路径,这样可以不用关心所用的环境变量,而Arguments是命令的参数,比如要查看phthon的版本,

1
2
3
4
var cmd = @"C:\Program Files/Python312/python.exe";
var args = "--version";

InvokeCommand(cmd, args);

2. Mac

经过多角度尝试,发现单单使用Process的方式是无法弹出新的终端窗口的,命令确实会执行,但是不会弹出新终端窗口,所以需要通过其他方式辅助实现。

Mac系统自带一个osascript命令,这个命令是用来执行Apple Script的,可以基于Mac系统本身实现多种效果,所以是可以实现弹出新终端窗口目的的,所以我们需要写一个Apple Script,实现开启新窗口执行命令,然后再通过Process调用Apple Script即可

1
2
3
4
tell application "Terminal"
activate
do script "[cmmand] [options]"
end tell

其中,command即为我们需要执行的命令,同样建议使用绝对路径,可以不用管环境变量。在执行Process前,完善Apple Script,然后调用即可,其扩展名为.scpt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void InvokeCommand(stirng cmd, string args)
{
var appleScriptPath = "path/to/save/apple/script.scpt"
var scriptTemplate = @"tell application ""Terminal""
activate
do script ""{0} {1}""
end tell";
var script = string.Format(scriptTemplate, cmd, args);
File.WriteAllText(appleScriptPath, script);

var proc = new Process();
proc.StartInfo.FileName = "/usr/bin/osascript";
proc.StartInfo.Arguments = appleScriptPath;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.UseShellExecute = true;
proc.Start();
proc.WaitForExit();
proc.Close();
}

3. 异步执行

如果在代码中不需要等待命令行执行结束,去掉Wait和Close,便可异步执行命令,

1
2
3
var proc = new Process();
.....
proc.Start();
------------- (完) -------------
  • 本文作者: oynix
  • 本文链接: https://oynix.net/2024/02/e0d6075deeb3/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

欢迎关注我的其它发布渠道