3

I've made a C++ code editor in C# and now am trying to invoke g++ to compile the source files. So I've copied the TDM-GCC installation besides my program and wrote a small batch script to call that.

@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

And from C# code, I'm trying to call this script by using CMD like in this script of code.

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

And here is the StartProcess method:

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

Update: 26-9-14

I doubted whether the batch file is ever called, because if I call it from cmd, it simply works. So I tried to echo to the standard error from the batch file like this:

echo %PATH% 1>&2

And I can see that the GCC's bin folder is in the path too, but for some reason, the exe is not getting created. But sometimes, the script works, and the exe gets created.

But whenever I execute this, there will be nothing in the LOG and also, no executable is being created. I know that the TDM-GCC's bin folder must be in the PATH, but that is what the second line of the batch script needs to do. Dunno what this is and why this error.

End of update

Any suggestions on how can I get it working?

Thanks.

Sri Harsha Chilakapati
  • 11,744
  • 6
  • 50
  • 91
  • what do you see when you set hidden to false? what happens when you start the batch file from the command line? – ths Sep 26 '14 at 13:44
  • @ths When I start from commandline, the batch file works on my pc. But when I started from the process, it sometimes works and sometimes not. – Sri Harsha Chilakapati Sep 26 '14 at 13:53
  • "sometimes"? above, you say "whenever". so what is the difference between working and not working runs? – ths Sep 26 '14 at 14:03
  • @ths That's the progress in two days. Some times the exe is created, sometimes the compiler simply exits. – Sri Harsha Chilakapati Sep 26 '14 at 14:04
  • When you say the compiler simply exits, do you mean that it writes no messages both to stderr AND stdout? I see that in your code you just log StandardError - I assume you already tried checking StandardOutput as well, but I figure it doesn't hurt to ask anyway. – chris Sep 26 '14 at 14:08
  • @chris Yes I tried logging both, but of no use. It just prints a message saying that you are in MinGW Console, so I stopped logging the standard output. – Sri Harsha Chilakapati Sep 26 '14 at 14:10
  • Well, that's a mistake, you can easily deadlock the program when it sends too much output to stdout. If you're not interested in it then you *must* set RedirectStandardOutput to *false*. If you are then you *must* use BeginErrorReadLine + BeginOutputReadLine instead. – Hans Passant Sep 26 '14 at 14:15
  • @HansPassant I didn't get that. When I set `RedirectStandardOutput` to false, it echoes 'invalid handle' to stderr. Didn't understand what that meant. – Sri Harsha Chilakapati Sep 26 '14 at 14:18
  • Well, not every program supports that and g++ is certainly an odd-ball. Nothing you can but redirect it. *Do* read it, having cmd.exe take care of the redirection is [worth a try](http://stackoverflow.com/a/20789248/17034). – Hans Passant Sep 26 '14 at 14:41
  • @HansPassant I always wonder how the IDEs that come with pre-bundled GCC get it to work. Any ideas please? – Sri Harsha Chilakapati Sep 26 '14 at 14:51
  • They always redirect to a file instead. – Hans Passant Sep 26 '14 at 14:55
  • @HansPassant I'll try redirection and see if it works. Not sure though. – Sri Harsha Chilakapati Sep 26 '14 at 15:15

2 Answers2

1

I don't know if anything written below really helps on this issue. But at least those hints should be useful in any case.

I suggest for the batch file

@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 is modified after execution of mingwvars.bat. It could be that this batch file also modifies PATH. Or it runs commands like find.exe with the executables expected in %SystemRoot%\System32, but perhaps also existing in directory bin. I have seen already several times not working logon batch scripts because PATH on client computer contained as first folder path the bin directory of a compiler ported from Unix to Windows with executables also found in %SystemRoot%\System32, but working completely different as ported from Unix.

Folder paths should be added to environment variable PATH always without double quotes even if the folder path contains 1 or more spaces. The double quotes used in third line just make sure that a trailing space is not added additionally to PATH and that command set works even with not typical folder paths like an ampersand in path.

And folder paths should be added to environment variable PATH without a trailing backslash.

On command cd the parameter /D is additionally used in case of a change to a different drive must be performed, too. The command cd would not change the current directory if the specified path is on a different drive without parameter /D.

In C# code you have to make sure that workingDir, fileName and exeName are finally on execution of cmd.exe enclosed in double quotes in the arguments string as Erti-Chris Eelmaa already wrote.

And it would be perhaps better to read in your C# application the value of environment variable ComSpec and use this value instead of just cmd for executing the batch file.

Community
  • 1
  • 1
Mofi
  • 46,139
  • 17
  • 80
  • 143
0

This might, or might not be part of the problem, but you don't take care of spaces.

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

you probably would want something like this:

pStartInfo.Arguments = string.Join(" ", args.Select(x => "\"" + x + "\""));
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78