2011-03-30 24 views
8

-edit- parece ser un problema con la ruta y no ser capaz de encontrar su bin/carpeta. Aunque el g ++ está en ese directorio bin.gcc/g ++ me da error "CreateProcess: No existe tal archivo o directorio"

Estoy tratando de iniciar g ++ en Windows en mi aplicación, pero me sale el siguiente error. ¿Cómo lo arreglo? nota lateral puedo hacer g++ dummy.cpp en el prompt sin ningún problema.

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

stdout

: CreateProcess: No such file or directory 

operación -Editar- mi código es ...

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

podría ser útil publicar el código que utiliza para llamar a gcc desde su aplicación. Sospecho que necesitarás especificar la ruta completa al ejecutable gcc, ya que es muy probable que no haya una "ruta de búsqueda" como en el intérprete de comandos. – lothar

+0

¿El error proviene de su llamada? Por lo que entiendo cómo funciona gcc/g ++, comienzan otro proceso y puede ser que no puedan encontrarlos. ¿Es su símbolo del sistema donde g ++ funciona el símbolo del sistema de Windows normal o Cygwin? –

+0

@lothar: Listo. @Alexey: en cmd, g ++ funciona. Con mi código C++ (ahora pegado). Lo ejecuto y obtengo el error. El error es de g ++ stdout. –

Respuesta

3

Qué GCC para Windows está usando? MinGW, Cygwin, ¿algo más?

¿Ha intentado iniciar o cerrar sesión nuevamente como se indica en esta pregunta? CreateProcess: No such file or directory

En Windows, GCC necesita que su directorio bin esté en la RUTA, no se verá en el directorio de su propio binario. Trate de poner algo así como

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

en su programa antes de la llamada a g ++ para asegurarse de que el directorio está en el camino para el entorno de su programa (si no se está ejecutando el programa en un depurador, utilice wprintf lugar)

Tenga cuidado si ha intentado instalar GCC en una ruta con un carácter de espacio en ella, tanto MinGW como Cygwin advierten contra esto.

+0

. Lo intenté pero quizás lo hice mal. Agregué mi código de arriba. Añadiendo 'path = gcc_bin; path; \ 0 \ 0' causa error' 87 parámetro es incorrecto' cuando intenté ejecutar mi createproccess. –

+0

aparece "E:/dev/external/MinGW/bin" en buf? De lo contrario, debe agregarlo al entorno de su sistema (http: // support.microsoft.com/kb/310519 en XP, Windowskey -> "entorno" en Vista/7) e inicie sesión y vuelva a iniciar sesión. – BCoates

+0

Otras personas tendrán que usar esta aplicación y no quiero perder el tiempo con sus entornos vars. Además, lo agrego a ExpandEnvironmentStrings como muestra mi código. Es solo que lo hago mal o algo así porque obtengo el error de parámetro cuando llamo a mi propio createproccess –

0

tengo un problema ayer con un programa de no ser capaz de manejar una ruta como esta:

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

lo sustituyó con:

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

y funcionó. Es posible que desee comprobar esto

6

intenta agregar el camino hacia g ++ compilador en PATH variable de entorno:

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; 

En este bloque de entorno punto de su proceso contiene PATH variable que incluye la ruta al compilador g ++. Nota: esto no afecta el entorno del usuario.

Puede usar char en lugar de TCHAR y strcpy, strcat. De esta manera funcionará en ambos casos: con Unicode habilitado y sin soporte Unicode.

1

Utilice Sysinternals ProcessMonitor (http://technet.microsoft.com/en-us/sysinternals/bb896645) para rastrear las llamadas al sistema emitidas por su código (CreateFile, CreateProcess, consultas del Registro) junto con su éxito y valor de retorno Esto también muestra todos los diferentes intentos de encontrar el ejecutable que no es encontrado por su código - la mayoría de las veces esto lo hace obvio, qué error (por ejemplo, error tipográfico, escape, espacio en blanco en la ruta, etc.) causaba que el código no encontrara el ejecutable g ++ .

1

Use Sysinternals ProcessMonitor como dijo BertNase. Lo que haces es encontrar el.nombre del exe que está haciendo la compilación en la columna Nombre del proceso, como gcc.exe. Luego mira en la columna de resultados y cualquier cosa que no sea un ÉXITO, échale un vistazo. Creo que lo que estás buscando es un resultado NOMBRE NO ENCONTRADO.

Tuve el mismo problema e hice lo que acabo de mencionar, encontré que gcc.exe estaba obteniendo un resultado NOMBRE NO ENCONTRADO para cc1obj.exe. Así que hice una conjetura y ingresé a mi carpeta MinGW bajo \ libexec \ gcc \ mingw32 \ 4.5.0 (el número de versión podría no ser el mismo para usted) e hice una copia de cc1.exe y luego lo renombré como cc1obj.exe . Y wala, eso solucionó el problema.

Probablemente no te falte el mismo archivo, pero parece que seguir este proceso lo arreglará.

0

El error que recibe dice que la función de gcc "CreateProcess" intenta acceder a algún archivo y no puede encontrarlo.

Obviamente si gcc detecta el error, se está ejecutando, por lo que no hay nada de malo con su RUTA.

Sin embargo, gcc no puede encontrar un programa o una biblioteca necesarios para la compilación. Es un extraño error que conozco en mingw32. Mi mejor consejo será volver a instalar mingw32. Es posible que haya cambiado el uso de algunos archivos por parte del programa.

4

Es muy probable que existan instancias dobles del compilador en el sistema.

Si es así, intente lo siguiente para el experimento de manera que el que está bajo ruta actual podría funcionar para la compilación fuente:

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

la esperanza que esto podría ser de ayuda. Saludos.

2

He tenido el mismo problema y he resuelto después de agregar el "C: \ MinGW \ msys \ 1.0 \ bin" a la variable del sistema PATH.

0

También me he enfrentado al problema al configurar Atom. Pero más tarde descubrí que mi MinGW se copió de la carpeta Codeblocks. Volver a instalar los paquetes a través del instalador oficial MinGW y la adición de la ruta del directorio (para mi caso C: \ MinGW \ bin) en

anticipadas Ajustes del sistema> Variables de entorno> Ruta

resuelto el problema para mí

Cuestiones relacionadas