gcc / g ++ выдает ошибку «CreateProcess: нет такого файла или каталога» - PullRequest
9 голосов
/ 30 марта 2011

-edit- похоже, что проблема с путем и невозможностью найти его папку / папку.Несмотря на то, что g ++ находится в этом каталоге bin.

Я пытаюсь запустить g ++ на окнах в моем приложении, но я получаю ошибку ниже.Как мне это исправить?примечание стороны, я могу сделать g++ dummy.cpp в приглашении без проблем.

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

stdout

: CreateProcess: No such file or directory

-edit- мой код ...

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

Ответы [ 10 ]

6 голосов
/ 11 апреля 2011

Попробуйте добавить путь к компилятору g ++ в PATH переменную среды:

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;

На данный момент блок среды вашего процесса содержит переменную PATH, которая включает путь к компилятору g ++.Примечание: это не влияет на среду пользователя.

Вы можете использовать char вместо TCHAR и strcpy, strcat.Этот способ будет работать в обоих случаях: с включенным Юникодом и без поддержки Юникода.

4 голосов
/ 06 октября 2012

Весьма вероятно, что в системе существуют двойные экземпляры компилятора.

Если так, попробуйте следующее для эксперимента, чтобы тот, который находится под текущим путем, мог работать для исходной компиляции:

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

Надеюсь, это поможет.С уважением.

3 голосов
/ 08 апреля 2011

Какой GCC для Windows вы используете? MinGW, Cygwin, что-то еще?

Вы пытались войти и выйти снова, как указано в этом вопросе? CreateProcess: нет такого файла или каталога

В Windows GCC требуется, чтобы его каталог bin находился в PATH, он не будет искать в каталоге своего двоичного файла. Попробуйте поставить что-то вроде

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

в вашу программу перед вызовом g ++, чтобы убедиться, что каталог находится в пути к среде вашей программы (если вы не запускаете свою программу в отладчике, используйте вместо этого wprintf)

Остерегайтесь, если вы пытались установить GCC по пути с пробелом в нем, и MinGW, и Cygwin предупреждают об этом.

2 голосов
/ 06 июня 2013

У меня возникла та же проблема, и она была решена после добавления «C: \ MinGW \ msys \ 1.0 \ bin» в системную переменную PATH.

1 голос
/ 24 апреля 2011

Используйте Sysinternals ProcessMonitor, как сказал BertNase.Что вы делаете, это найти .exe имя, которое выполняет компиляцию в столбце Имя процесса, например, gcc.exe.Затем загляните в столбец Result и проверьте все, что не является УСПЕХОМ.Я думаю, что вы ищете результат ИМЯ НЕ НАЙДЕН.

У меня была такая же проблема, и я сделал то, что только что упомянул выше, я обнаружил, что gcc.exe получает результат ИМЯ НЕ НАЙДЕН для cc1obj.EXE.Поэтому я сделал обоснованное предположение и зашел в свою папку MinGW по адресу \ libexec \ gcc \ mingw32 \ 4.5.0 (номер версии может не совпадать для вас) и сделал копию cc1.exe, а затем переименовал ее в cc1obj.exe,И вот, это решило проблему.

Возможно, вы не пропустили один и тот же файл, но похоже, что следующий процесс исправит его.

1 голос
/ 11 апреля 2011

Используйте Sysinternals ProcessMonitor (http://technet.microsoft.com/en-us/sysinternals/bb896645) для отслеживания системных вызовов, которые выдает ваш код (CreateFile, CreateProcess, запросы Registry), а также их успешное и возвращаемое значение. Это также показывает все различные попытки найти исполняемый файл, который не является найденный вашим кодом - в большинстве случаев это делает очевидным, какая ошибка (например, опечатка, экранирование, пробелы в пути и т. д.) привела к тому, что код не нашел исполняемый файл g ++.

0 голосов
/ 08 января 2019

Старый поток, но кто знает, что может помочь.

Для меня я заменил полный путь на местоположение компилятора.

Итак:

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

Я думаю, что, возможно, текущий путь содержит некоторые элементы, которые не анализируются компилятором должным образом (без двойных кавычек, без пробелов и т. Д.)

0 голосов
/ 14 января 2017

Я также столкнулся с проблемой при настройке Atom. Но позже я узнал, что мой MinGW был скопирован из папки Codeblocks. Переустановка пакетов через официальный установщик MinGW и добавление пути к каталогу (для моего случая C: \ MinGW \ bin) в

Дополнительные параметры системы> Переменные среды> Путь

решил проблему для меня

0 голосов
/ 19 января 2012

Полученная ошибка говорит о том, что функция gcc «CreateProcess» пытается получить доступ к какому-либо файлу и не может его найти.

Очевидно, что если gcc перехватит ошибку, она будет запущена, так что с вашим PATH все в порядке.,

Однако gcc не может найти программу или библиотеку, необходимую для компиляции.Это странная ошибка, которую я знаю на mingw32.Мой лучший совет будет переустанавливать mingw32.Возможно, вы изменили использование файла некоторыми программами.

0 голосов
/ 08 апреля 2011

Вчера у меня возникла проблема с программой, которая не может обработать путь, подобный этому:

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

Я заменил его на:

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

и это сработало. Вы можете проверить это

...