使用 Windows 窗体应用程序在 C 中编译

本文关键字:编译 应用程序 Windows 窗体 使用 | 更新日期: 2023-09-27 18:32:22

我正在使用Visual Studio 2010在C#中创建一个编译器应用程序。

此程序的目标是在运行时编译用 C# 或 C 编写的代码,并返回编译结果。

我已经完成了 C# 部分,但 C 部分是我遇到的问题。对于这个,我尝试使用Visual Studio命令提示符。我编码这部分的方式是这样的:

  1. 在 C:'' 中创建 .c 文件使用文件创建。
  2. 使用进程,打开 Visual Studio 命令提示符并执行编译。
  3. 捕获输出以将其作为编译结果返回。

但是,它不起作用。它抛出和 Win32 异常,但我真的不知道为什么。

我听说过一些关于使用 gcc 的事情。但是我想过使用Visual Studio命令提示符作为可能的解决方案。

编辑:我想出了这样做的步骤(我认为)。但是当程序尝试执行该过程时,会出现 Win32 异常。开始() 行。我想这可能是权限问题,但我真的不知道。

使用 Windows 窗体应用程序在 C 中编译

我的一个朋友也做了类似的事情,并帮助我解决了这个问题。

在步骤 2 和 3 中,我尝试仅使用过程标准输入和输出来编写输入并读取输出,并且还尝试使用.lnk来运行命令提示符。所有这些事情都导致了错误。

解决方案是:

  1. 创建两个批处理文件,一个用于启动命令提示符,另一个用于编译 .c 文件(这些文件是在程序代码之外创建的)。
  2. (在运行时)使用编写的代码创建 .c 文件。如果文件存在,请将其删除并创建一个新文件。
  3. 使用 cmd.exe 开始该过程。
  4. 运行批处理文件,使用流编写器将它们写入 cmd.exe。
  5. 使用流读取器检索输出。

幸运的是,这奏效了!代码是这样结束的:

string CompileC (string code)
{
    string path = @"C:'sample.c";
    string results = "";
    try
    {
        if (File.Exists(path))
            File.Delete(path);
        using (FileStream fs = File.Create(path))
        {
            byte[] codeText = new UTF8Encoding(true).GetBytes(code);
            fs.Write(codeText, 0, codeText.Length);
        }
        Process process = new Process();
        process.StartInfo.FileName = @"C:'Windows'system32'cmd.exe";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardInput = true;
        process.StartInfo.RedirectStandardOutput = true;
        process.Start();
        using (StreamWriter sw = process.StandardInput)
        {
            if (sw.BaseStream.CanWrite)
            {
                //This batch starts up the Visual Studio Command Prompt.
                sw.WriteLine(@"C:'Startup.bat");
                //This batch does the compilation, once the Command Prompt
                //is running, using the 'cl' command.
                sw.WriteLine(@"C:'Compile.bat");
            }
        }
        using (StreamReader sr = process.StandardOutput)
        {
            if (sr.BaseStream.CanRead)
                results = sr.ReadToEnd();
        }
    }
    catch (Exception ex) { MessageBox.Show(ex.ToString()); }
    return results;
}