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

时间:2014-11-29 05:37:46

标签: c# visual-studio-2010

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

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

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

  1. 使用File.Create在C:\中创建.c文件。
  2. 使用Process,打开Visual Studio命令提示符并执行编译。
  3. 捕获输出以将其作为编译结果返回。
  4. 但是,它不起作用。它会抛出Win32异常,但我不知道为什么。

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

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

1 个答案:

答案 0 :(得分:0)

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

在第2步和第3步,我试图编写输入并使用进程标准输入和输出读取输出,而且,我试图使用.lnk来运行命令提示符。所有这些都导致了错误。

解决方案是:

  1. 创建两个批处理文件,一个用于启动命令提示符,另一个用于编译.c文件(这些是在程序代码之外创建的)。
  2. (运行时)使用编写的代码创建.c文件。如果文件存在,请将其删除并创建一个新文件。
  3. 使用cmd.exe启动该过程。
  4. 使用Stream Writer运行批处理文件,将其写入cmd.exe。
  5. 使用Stream Reader检索输出。
  6. 幸运的是,这有效!代码结束如下:

    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;
    }