reconoce que para interno externo descargar compilar compilador como comando c++ windows winapi

que - ¿Cómo llamo a:: CreateProcess en c++ para lanzar un ejecutable de Windows?



g++ no se reconoce como un comando interno o externo (8)

Buscando un ejemplo que:

  1. Lanza un EXE
  2. Espera a que el EXE termine.
  3. Correctamente cierra todos los identificadores cuando termina el ejecutable.

Algo como esto:

STARTUPINFO info={sizeof(info)}; PROCESS_INFORMATION processInfo; if (CreateProcess(path, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo)) { WaitForSingleObject(processInfo.hProcess, INFINITE); CloseHandle(processInfo.hProcess); CloseHandle(processInfo.hThread); }


Aquí hay un nuevo ejemplo que funciona en Windows 10. Cuando usa el sdk de windows10, tiene que usar CreateProcessW en su lugar. Este ejemplo está comentado y, con suerte, se explica por sí mismo.

#ifdef _WIN32 #include <windows.h> #include <stdio.h> #include <tchar.h> #include <cstdlib> #include <string> #include <algorithm> class process { public: static PROCESS_INFORMATION launchProcess(std::string app, std::string arg) { // Prepare handles. STARTUPINFO si; PROCESS_INFORMATION pi; // The function returns this ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); //Prepare CreateProcess args std::wstring app_w(app.length(), L'' ''); // Make room for characters std::copy(app.begin(), app.end(), app_w.begin()); // Copy string to wstring. std::wstring arg_w(arg.length(), L'' ''); // Make room for characters std::copy(arg.begin(), arg.end(), arg_w.begin()); // Copy string to wstring. std::wstring input = app_w + L" " + arg_w; wchar_t* arg_concat = const_cast<wchar_t*>( input.c_str() ); const wchar_t* app_const = app_w.c_str(); // Start the child process. if( !CreateProcessW( app_const, // app path arg_concat, // Command line (needs to include app path as first argument. args seperated by whitepace) NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent''s environment block NULL, // Use parent''s starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { printf( "CreateProcess failed (%d)./n", GetLastError() ); throw std::exception("Could not create child process"); } else { std::cout << "[ ] Successfully launched child process" << std::endl; } // Return process handle return pi; } static bool checkIfProcessIsActive(PROCESS_INFORMATION pi) { // Check if handle is closed if ( pi.hProcess == NULL ) { printf( "Process handle is closed or invalid (%d)./n"); return FALSE; } // If handle open, check if process is active DWORD lpExitCode = 0; if( GetExitCodeProcess(pi.hProcess, &lpExitCode) == 0) { printf( "Cannot return exit code (%d)./n", GetLastError() ); throw std::exception("Cannot return exit code"); } else { if (lpExitCode == STILL_ACTIVE) { return TRUE; } else { return FALSE; } } } static bool stopProcess( PROCESS_INFORMATION &pi) { // Check if handle is invalid or has allready been closed if ( pi.hProcess == NULL ) { printf( "Process handle invalid. Possibly allready been closed (%d)./n"); return 0; } // Terminate Process if( !TerminateProcess(pi.hProcess,1)) { printf( "ExitProcess failed (%d)./n", GetLastError() ); return 0; } // Wait until child process exits. if( WaitForSingleObject( pi.hProcess, INFINITE ) == WAIT_FAILED) { printf( "Wait for exit process failed(%d)./n", GetLastError() ); return 0; } // Close process and thread handles. if( !CloseHandle( pi.hProcess )) { printf( "Cannot close process handle(%d)./n", GetLastError() ); return 0; } else { pi.hProcess = NULL; } if( !CloseHandle( pi.hThread )) { printf( "Cannot close thread handle (%d)./n", GetLastError() ); return 0; } else { pi.hProcess = NULL; } return 1; } };//class process #endif //win32


En una nota semi relacionada, si desea iniciar un proceso que tiene más privilegios que su proceso actual (por ejemplo, iniciar una aplicación de administrador, que requiere derechos de administrador, desde la aplicación principal ejecutándose como un usuario normal), no puede hágalo utilizando CreateProcess () en Vista, ya que no activará el cuadro de diálogo UAC (suponiendo que esté habilitado). Sin embargo, el cuadro de diálogo UAC se activa cuando se usa ShellExecute ().


Hay un ejemplo en

Simplemente reemplace el argv[1] con su constante o variable que contiene el programa.

#include <windows.h> #include <stdio.h> #include <tchar.h> void _tmain( int argc, TCHAR *argv[] ) { STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); if( argc != 2 ) { printf("Usage: %s [cmdline]/n", argv[0]); return; } // Start the child process. if( !CreateProcess( NULL, // No module name (use command line) argv[1], // Command line NULL, // Process handle not inheritable NULL, // Thread handle not inheritable FALSE, // Set handle inheritance to FALSE 0, // No creation flags NULL, // Use parent''s environment block NULL, // Use parent''s starting directory &si, // Pointer to STARTUPINFO structure &pi ) // Pointer to PROCESS_INFORMATION structure ) { printf( "CreateProcess failed (%d)./n", GetLastError() ); return; } // Wait until child process exits. WaitForSingleObject( pi.hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); }


Si su aplicación es una aplicación GUI de Windows, usar el siguiente código para hacer la espera no es ideal ya que los mensajes de su aplicación no recibirán procesamiento. Para el usuario, se verá como si tu aplicación se hubiera colgado.

WaitForSingleObject(&processInfo.hProcess, INFINITE)

Algo como el código no probado a continuación podría ser mejor, ya que seguirá procesando la cola de mensajes de Windows y su aplicación seguirá siendo receptiva:

//-- wait for the process to finish while (true) { //-- see if the task has terminated DWORD dwExitCode = WaitForSingleObject(ProcessInfo.hProcess, 0); if ( (dwExitCode == WAIT_FAILED ) || (dwExitCode == WAIT_OBJECT_0 ) || (dwExitCode == WAIT_ABANDONED) ) { DWORD dwExitCode; //-- get the process exit code GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode); //-- the task has ended so close the handle CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); //-- save the exit code lExitCode = dwExitCode; return; } else { //-- see if there are any message that need to be processed while (PeekMessage(&message.msg, 0, 0, 0, PM_NOREMOVE)) { if (message.msg.message == WM_QUIT) { return; } //-- process the message queue if (GetMessage(&message.msg, 0, 0, 0)) { //-- process the message TranslateMessage(&pMessage->msg); DispatchMessage(&pMessage->msg); } } } }



Tenga en cuenta que usar WaitForSingleObject puede WaitForSingleObject en problemas en este escenario. Lo siguiente está recortado de un consejo en mi sitio web:

El problema surge porque su aplicación tiene una ventana pero no está bombeando mensajes. Si la aplicación generada invoca SendMessage con uno de los destinos de difusión ( HWND_BROADCAST o HWND_TOPMOST ), SendMessage no volverá a la nueva aplicación hasta que todas las aplicaciones hayan manejado el mensaje, pero su aplicación no puede manejar el mensaje porque no es así. t bombeo de mensajes ... por lo que la nueva aplicación se bloquea, por lo que su espera nunca tendrá éxito ... MUERTO DEMORA.

Si tiene control absoluto sobre la aplicación engendrada, entonces hay medidas que puede tomar, como usar SendMessageTimeout en lugar de SendMessage (por ejemplo, para iniciaciones DDE, si alguien todavía está usando eso). Pero hay situaciones que provocan transmisiones implícitas de SendMessage sobre las cuales no tiene control, como por ejemplo el uso de la API SetSysColors.

Las únicas formas seguras de esto son:

  1. dividir la espera en un hilo separado, o
  2. use un tiempo de espera en Wait y use PeekMessage en su ciclo de espera para asegurarse de que usted bombea mensajes, o
  3. usa la API MsgWaitForMultipleObjects .