gcc/g++ gives me error “CreateProcess: No such fil

2020-08-26 03:49发布

问题:

-edit- it seems to be a problem with path and not being able to find its bin/ folder. Even though the g++ is in that bin directory.

I am trying to launch g++ on windows in my app but i get the error below. How do i fix it? side note i can do g++ dummy.cpp in the prompt with no problem.

args -o file.exe -x c++ -

stdout

: CreateProcess: No such file or directory

-edit- my code is...

#include <windows.h> 
#include <stdio.h> 
#include <strsafe.h>

#include <ios>
#include <iostream>
#include <fstream>
#include <sstream>
#include <exception>
#include <string>
#include <deque>
#include <stdio.h>
#include <stdlib.h>

using namespace std;

string gcc_bin="E:/dev/external/MinGW/bin/g++.exe";
string gcc_folder="E:/dev/external/MinGW/bin/";

int launch_gcc(ostringstream&o);
int main(){
    ostringstream osz;
    osz << "#include <cstdio>" << endl << "int main(){ printf(\"hello\"); } return 4; }";
    {
        launch_gcc(osz);
    }
    return 0;
}





void ErrorExit(PTSTR);
int launch_gcc(ostringstream&o)
{

    char buf2[4096];
char buf[4096];
ExpandEnvironmentStrings("%PATH%", buf, 4095);
OutputDebugString(buf);

    sprintf(buf2, "PATH=%s;%s;\0\0", gcc_folder.c_str(), buf);

    STARTUPINFO startupInfo;
    PROCESS_INFORMATION processInformation;

    HANDLE g_hChildStd_IN_Rd = NULL;
    HANDLE g_hChildStd_IN_Wr = NULL;
    HANDLE g_hChildStd_OUT_Rd = NULL;
    HANDLE g_hChildStd_OUT_Wr = NULL;
    HANDLE g_hChildStd_ERR_Rd = NULL;
    HANDLE g_hChildStd_ERR_Wr = NULL;

    HANDLE g_hInputFile = NULL;

    SECURITY_ATTRIBUTES saAttr;  
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saAttr.bInheritHandle = TRUE; 
    saAttr.lpSecurityDescriptor = NULL; 

    if ( ! CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0) ) 
    ErrorExit(TEXT("StdoutRd CreatePipe")); 
    if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
    ErrorExit(TEXT("Stdout SetHandleInformation"));

    if ( ! CreatePipe(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, &saAttr, 0) ) 
    ErrorExit(TEXT("StderrRd CreatePipe")); 
    if ( ! SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0) )
    ErrorExit(TEXT("Stderr SetHandleInformation"));

    if (! CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0)) 
    ErrorExit(TEXT("Stdin CreatePipe")); 
    if ( ! SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0) )
    ErrorExit(TEXT("Stdin SetHandleInformation")); 

    ZeroMemory( &startupInfo, sizeof(STARTUPINFO) );
    startupInfo.cb = sizeof(STARTUPINFOA); 
    startupInfo.hStdError = g_hChildStd_OUT_Wr;
    startupInfo.hStdOutput = g_hChildStd_ERR_Wr;
    startupInfo.hStdInput = g_hChildStd_IN_Rd;
    startupInfo.dwFlags |= STARTF_USESTDHANDLES;

    ZeroMemory( &processInformation, sizeof(PROCESS_INFORMATION) );

    bool bSuccess = CreateProcess(
        gcc_bin.c_str(),
        " -o \"c:/dev/src/git/myprj/theout.exe\" -x c++ -",
0,
  0,
  1,
  NORMAL_PRIORITY_CLASS,
  0,//buf2,
  0,//gcc_folder.c_str(),
  &startupInfo,
  &processInformation
);
   if ( ! bSuccess ) 
      ErrorExit(TEXT("CreateProcess"));
   else 
   {
      // Close handles to the child process and its primary thread.
      // Some applications might keep these handles to monitor the status
      // of the child process, for example. 

      CloseHandle(processInformation.hProcess);
      CloseHandle(processInformation.hThread);
   }


    { 
    DWORD dwRead, dwWritten; 
    BOOL bSuccess = FALSE;

    auto sz=o.str();
    bSuccess = WriteFile(g_hChildStd_IN_Wr, sz.c_str(), sz.size(), &dwWritten, NULL);
    //if ( ! bSuccess ) break; 

    if ( ! CloseHandle(g_hChildStd_IN_Wr) ) 
        ErrorExit(TEXT("StdInWr CloseHandle")); 
    } 



    #define BUFSIZE 1024*4
    { 
    DWORD dwRead, dwWritten; 
    CHAR chBuf[BUFSIZE]; 
    BOOL bSuccess = FALSE;
    HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);

    chBuf[0]=0;
    if (!CloseHandle(g_hChildStd_OUT_Wr)) 
        ErrorExit(TEXT("StdOutWr CloseHandle")); 

    for (;;) 
    { 
        bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
        if( ! bSuccess || dwRead == 0 ) break; 

        bSuccess = WriteFile(hParentStdOut, chBuf, 
                            dwRead, &dwWritten, NULL);
        chBuf[dwWritten]=0;
        if (! bSuccess ){ 
            printf("%s", chBuf);
            break; 
        }
    } 
    }

    { 
    DWORD dwRead, dwWritten; 
    CHAR chBuf[BUFSIZE]; 
    BOOL bSuccess = FALSE;
    HANDLE hParentStdErr = GetStdHandle(STD_ERROR_HANDLE);

    if (!CloseHandle(g_hChildStd_ERR_Wr)) 
        ErrorExit(TEXT("StdOutWr CloseHandle")); 

    for (;;) 
    { 
        bSuccess = ReadFile( g_hChildStd_ERR_Rd, chBuf, BUFSIZE, &dwRead, NULL);
        if( ! bSuccess || dwRead == 0 ) break; 

        bSuccess = WriteFile(hParentStdErr, chBuf, 
                            dwRead, &dwWritten, NULL);
        chBuf[dwWritten]=0;
        if (! bSuccess ){ 
            printf("%s", chBuf);
            break; 
        }
    }
    auto a=1;
    }


    return 0;
}

void ErrorExit(PTSTR lpszFunction) 
{ 
    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(1);
}

回答1:

Try to add the path to g++ compiler into PATH environment variable:

TCHAR *path;
TCHAR *newpath;
DWORD dwSize = GetEnvironmentVariable(TEXT("PATH"), NULL, 0);

path = new TCHAR[dwSize];
GetEnvironmentVariable(TEXT("PATH"), path, dwSize);


dwSize += MAX_PATH;
newpath = new TCHAR[dwSize];
_tcscpy_s(newpath, dwSize, TEXT("E:\\dev\\external\\MinGW\\bin;"));
_tcscat_s(newpath, dwSize, path);
SetEnvironmentVariable(TEXT("PATH"), newpath);

delete[] path;
delete[] newpath;

At this point environment block of your process contains PATH variable that includes the path to g++ compiler. Note: this does not affect user's environment.

You can use char instead of TCHAR, and strcpy, strcat. This way will work in both cases: with Unicode enabled and without Unicode support.



回答2:

It is very likely that double instances of the compiler exist on the system.

If so, try the following for experiment so that the one under current path could run for the source compile:

D:\cmn_dev\mingw64\bin>.\g++ HelloGcc.cpp -o Hello.exe

Hope this could be of help. Regards.



回答3:

Which GCC for windows are you using? MinGW, Cygwin, something else?

Have you tried logging in and out again as indicated in this question? CreateProcess: No such file or directory

On Windows, GCC needs its bin directory to be on the PATH, it won't look in the directory of its own binary. Try putting something like

wchar_t buf[4096];
ExpandEnvironmentStringsW(L"%PATH%", buf, 4095);
OutputDebugStringW(buf);

into your program before the call to g++ to make sure the directory is on the path for your program's environment (if you're not running your program in a debugger, use wprintf instead)

Watch out if you tried to install GCC on a path with a space character in it, both MinGW and Cygwin warn against this.



回答4:

I have had the same issue and got it resolved after adding the "C:\MinGW\msys\1.0\bin" to the PATH system variable.



回答5:

Use Sysinternals ProcessMonitor (http://technet.microsoft.com/en-us/sysinternals/bb896645) to trace the system calls that are issued by your code (CreateFile, CreateProcess, Registry queries) along with their success and return value. This also shows all different attempts to find the executable which is not found by your code - most times this makes it obvious, which mistake (e.g. typo, escaping, white-space in path etc.) caused the code not to find the g++ executable.



回答6:

Use Sysinternals ProcessMonitor like BertNase said. What you do is find the .exe name that is doing the compiling under the Process Name column, like gcc.exe. Then look in the Result column and anything that is not a SUCCESS check it out. I think what you are looking for is a NAME NOT FOUND result though.

I had this same problem and did what I just mentioned above, I found that gcc.exe was getting a NAME NOT FOUND result for cc1obj.exe. So I made an educated guess and went into my MinGW folder under \libexec\gcc\mingw32\4.5.0 (the version number might not be the same for you) and made a copy of cc1.exe then renamed it as cc1obj.exe. And wala, that fixed the problem.

You probably aren't missing the same file but it sounds like following this process will fix it.



回答7:

I got a problem yesterday with a program not being able to handle a path like this:

<some stuff>;%ProgramFiles%\path\to\bins;<some other stuff>

I replaced it with :

<some stuff>;C:\Program Files\path\to\bins;<some other stuff>

and it worked. You might want to check this out



回答8:

The error you get say that the function of gcc "CreateProcess" try to access some file and can't find it.

Obviously if gcc catch the error, it's running, so nothing wrong with your PATH.

However gcc can't find a program or a library needed for the compilation. It's a strange error that I know on mingw32. My best advice will be to re-installed mingw32. You may have change some file use by the program.



回答9:

I have also faced the problem while setting up Atom. But later I found out that my MinGW was copied from Codeblocks folder. Reinstalling the packages through official MinGW installer and adding the directory path (for my case C:\MinGW\bin) in

Advance System Settings>Environment Variables > Path

solved the problem for me



回答10:

Old thread but who knows it can help.

For me, I replaced the complete path with the location of the compiler.

So:

set path="< folder that contains the compiler>"

I think that maybe the current path has some elements in it that are not parsed properly by the compiler (no double quotes, no spaces, etc)



标签: gcc g++