从C#程序调用G++

本文关键字:G++ 调用 程序 | 更新日期: 2023-09-27 18:24:27

我在C#中制作了一个C++代码编辑器,现在正试图调用g++来编译源文件。因此,除了我的程序之外,我还复制了TDM-GCC安装,并编写了一个小批量脚本来调用它。

@echo off
@set PATH="%~dp0TDM-GCC-32'bin'";%PATH%
call "%~dp0TDM-GCC-32'mingwvars.bat"
cd %1
"%~dp0TDM-GCC-32'bin'g++.exe" %2 -o %3

从C#代码中,我试图像在这个代码脚本中那样使用CMD来调用这个脚本。

string fileName   = Path.GetFileName(CurrentFile);
string exeName    = Path.GetFileNameWithoutExtension(CurrentFile) + ".exe";
string workingDir = Directory.GetParent(CurrentFile) + "";
string compile    = Directory.GetParent(Application.ExecutablePath) + "''compile.cmd";
File.Delete(Path.Combine(workingDir, exeName));
StartProcess(true, "cmd", "/c", "'"" + compile + "'"", workingDir, fileName, exeName);

这里是StartProcess方法:

void StartProcess(bool hidden, string command, params string[] args)
{
    ProcessStartInfo pStartInfo = new ProcessStartInfo();
    pStartInfo.FileName = command;
    pStartInfo.Arguments = string.Join(" ", args);
    pStartInfo.UseShellExecute = false;
    if (hidden)
    {
        pStartInfo.RedirectStandardError  = true;
        pStartInfo.RedirectStandardOutput = true;
        pStartInfo.CreateNoWindow = true;
    }
    Process proc = new Process();
    proc.StartInfo = pStartInfo;
    proc.Start();
    logBox.Clear();
    if (hidden)
    {
        while (!proc.StandardError.EndOfStream)
        {
            logBox.AppendText(GetTimestamp() + "  Error: " + proc.StandardError.ReadLine() + Environment.NewLine);
        }
    }
}

更新:26-9-14

我怀疑是否调用过批处理文件,因为如果我从cmd调用它,它就可以正常工作。所以我尝试从批处理文件中echo到标准错误,如下所示:

echo %PATH% 1>&2

我可以看到GCC的bin文件夹也在路径中,但由于某种原因,exe没有被创建。但有时,脚本会起作用,并创建exe。

但是,每当我执行此操作时,LOG中都不会有任何内容,也不会创建任何可执行文件。我知道TDM-GCC的bin文件夹必须在PATH中,但这就是批处理脚本的第二行需要做的。不知道这是什么以及为什么会出现这个错误。

更新结束

关于如何让它发挥作用,有什么建议吗?

谢谢。

从C#程序调用G++

我不知道下面写的东西是否真的有助于解决这个问题。但至少这些提示在任何情况下都应该是有用的。

我建议使用批处理文件

@echo off
call "%~dp0TDM-GCC-32'mingwvars.bat"
set "PATH=%~dp0TDM-GCC-32'bin;%PATH%"
cd /D %1
"%~dp0TDM-GCC-32'bin'g++.exe" %2 -o %3

PATH在执行mingwvars.bat之后被修改。可能是该批处理文件还修改了PATH。或者,它运行类似find.exe的命令,其中包含%SystemRoot%'System32中预期的可执行文件,但可能也存在于目录bin中。我已经见过好几次不使用登录批处理脚本,因为客户端计算机上的PATH包含从Unix移植到Windows的编译器的bin目录作为第一个文件夹路径,在%SystemRoot%'System32中也可以找到可执行文件,但与从Unix移植完全不同。

文件夹路径应添加到环境变量PATH中,即使文件夹路径包含1个或多个空格,也应始终不使用双引号。第三行中使用的双引号只是确保不会在PATH中添加尾随空格,并且命令set即使适用于路径中的"与"之类的非典型文件夹路径。

文件夹路径应添加到环境变量PATH中,不带尾部反斜杠。

在命令cd上,参数/D也被额外使用,以防必须执行对不同驱动器的更改。如果指定的路径在没有参数/D的不同驱动器上,则命令cd不会更改当前目录。

在C#代码中,您必须确保workingDirfileNameexeName最终执行了参数字符串中用双引号括起来的cmd.exe,正如Erti Chris Eelma所写的那样。

最好在C#应用程序中读取环境变量ComSpec的值,并使用该值而不是仅使用cmd来执行批处理文件。

这可能是,也可能不是问题的一部分,但您不需要注意空格。

pStartInfo.Arguments = string.Join(" ", args);

你可能想要这样的东西:

pStartInfo.Arguments = string.Join(" ", args.Select(x => "'"" + x + "'""));