使用 putenv 和 getpid 在 C 中使用 CreateProcess 获取错误

Getting errors with CreateProcess in C using putenv and getpid

我收到这些错误,但我到处寻找答案,但没有找到解决方案:

launcher.c:107:12: warning: implicit declaration of function 'putenv'
launcher.c:116:10: warning: passing argument 2 of 'CreateProcessA' makes pointer from integer without a cast
c:\cs30200\mingw32\bin\../lib/gcc/mingw32/4.5.1/../../../../include/winbase.h:1250:24: 
note: expected 'LPSTR' but argument is of type 'int'

我的错误在 putenv()CreateProcess() 上。我确实知道 putenv() returns 和 int,但我无法让新的命令提示符显示新的行标题。但是,我也遇到了 getpid() 的问题,每个程序的起始编号都相同。我以前用过,现在找不到哪里出错了。

#include <windows.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

void printError(char* functionName);
#define INFO_BUFFER_SIZE 32767
    
int main(void)
{
   int numInput;
   int x=1,y=1;
   static char *promptCmd = "PROMPT=Speak$sUp:$G";
   DWORD dwExitCode = 0;
       
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
       
   pid_t pid;
   pid = getpid();
    
   STARTUPINFO suNW;
   PROCESS_INFORMATION piNW;
   suNW.cb = sizeof(suNW);
   suNW.lpReserved = NULL;
   suNW.dwFlags = 0;
   suNW.cbReserved2 = 0;
   suNW.lpReserved2 = NULL; 
   suNW.lpDesktop = NULL;
   suNW.lpTitle = "What is your command?";
   suNW.dwX = x;
   suNW.dwY = y;
   suNW.dwXSize = CW_USEDEFAULT;
   suNW.dwYSize = CW_USEDEFAULT;
   suNW.dwFillAttribute = FOREGROUND_INTENSITY| FOREGROUND_GREEN|FOREGROUND_RED|BACKGROUND_RED;
   suNW.dwFlags = STARTF_USEPOSITION|STARTF_USEFILLATTRIBUTE;
   suNW.wShowWindow = TRUE;
   suNW.hStdInput = NULL;
   suNW.hStdOutput = NULL;
   suNW.hStdError = NULL;
    
   HANDLE hProc;
   hProc = pi.hProcess;
   GetStartupInfo(&si);
    
   const size_t full_size=256;
   TCHAR  sysLoc[INFO_BUFFER_SIZE],lpCommandLine[5][INFO_BUFFER_SIZE];
   char * progLoc;
    
   GetSystemDirectory(sysLoc, INFO_BUFFER_SIZE);                  //Get location of System32 folder
   progLoc = getenv("ProgramFiles(x86)");                         //Get location of Program Files folder x64
   if (progLoc==NULL) progLoc = getenv("ProgramFiles");           //If running x86 get location of Program Files folder
     
   snprintf(lpCommandLine[1],full_size,"%s\notepad.exe",sysLoc);
   snprintf(lpCommandLine[2],full_size,"%s\cmd.exe",sysLoc);
   snprintf(lpCommandLine[3],full_size,"%s\nslookup.exe",sysLoc);
   snprintf(lpCommandLine[4],full_size,"%s\charmap.exe",sysLoc);
   snprintf(lpCommandLine[5],full_size,"%s\Windows NT\Accessories\wordpad.exe",progLoc);
    
runProgram:
   printf("Which program would you like to run:\n");
   printf("0: Quit\n");
   printf("1: Run Notepad\n");
   printf("*2: Run cmd shell\n");
   printf("#3: Run NS LooKUp\n");
   printf("4: Run Character Map\n");
   printf("5: Run WordPad\n");
   printf("Enter your choice now: ");
   scanf("%d", &numInput);
       
   switch(numInput)
   {
       case 0:
          
           exit(0);
             
       case 1:
            
           if(TRUE==CreateProcessA(NULL,lpCommandLine[1], NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
           {
               printf("Started program 1 with pid = %i",getpid());//pid);
           }  
           else printError(lpCommandLine[1]);
             
           printf("\n\n");
           goto runProgram;
           break;
             
       case 2:
             
           if (CreateProcess(
               lpCommandLine[2],         // LPCTSTR lpApplicationName
               promptCmd,//putenv(promptCmd),               // LPTSTR lpCommandLine
               NULL,                // LPSECURITY_ATTRIBUTES lpProcessAttributes
               NULL,                // LPSECURITY_ATTRIBUTES lpThreadAttributes
               FALSE,//TRUE,               // BOOL bInheritHandles
               CREATE_NEW_CONSOLE,    // DWORD dwCreationFlags
               NULL,                // LPVOID lpEnvironment
               NULL,                // LPCTSTR lpCurrentDirectory
               &suNW,       // LPSTARTUPINFO lpStartupInfo
               &piNW        // LPPROCESS_INFORMATION lpProcessInformation
           ))
           {
               printf("Started program 2 with pid = %i \n",getpid());//pid);
               printf("  waiting for program 2 to terminate...\n");

               WaitForSingleObject(piNW.hProcess,INFINITE);
               CloseHandle(piNW.hThread);

               GetExitCodeProcess(piNW.hProcess,&dwExitCode);                  

               CloseHandle(piNW.hProcess);   
           }  
           else printError(lpCommandLine[2]);
             
           printf("  program 2 exited with a return value %i\n", dwExitCode);
           printf("\n\n");
           goto runProgram;
           break;     
          
       case 3:
           if(CreateProcessA(NULL, lpCommandLine[3], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)){ 
               printf("Started program 3 with pid = %i \n",getpid());//pid);
               WaitForSingleObject(pi.hProcess,INFINITE);
               CloseHandle(pi.hThread);
               CloseHandle(pi.hProcess);    
               goto runProgram;
           }  
           else printError(lpCommandLine[3]);
             
           printf("\n");
           goto runProgram;
           break;     
          
       case 4:
           if(CreateProcessA(NULL,lpCommandLine[4], NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
           { 
               printf("Started program 4 with pid = %i \n",getpid());//pid);
               CloseHandle(pi.hThread);
               CloseHandle(pi.hProcess); 
           }
           else printError(lpCommandLine[4]);
                
           printf("\n\n"); 
           goto runProgram;
           break;     
          
       case 5:
           if(CreateProcessA(NULL,lpCommandLine[5], NULL,NULL,FALSE,0,NULL,NULL,&si,&pi))
           { 
               printf("Started program 5 with pid = %i \n",getpid());//pid);
               CloseHandle(pi.hThread);
               CloseHandle(pi.hProcess); 
           }
           else printError(lpCommandLine[5]);
                
           printf("\n\n");
           goto runProgram;
           break;
   }
       
   return 0;
}
    
/****************************************************************
 The following function can be used to print out "meaningful"
 error messages. If you call a Win32 function and it returns
 with an error condition, then call this function right away and
 pass it a string containing the name of the Win32 function that
 failed. This function will print out a reasonable text message
 explaining the error and then (if chosen) terminate the program.
*/
void printError(char* functionName)
{
   LPVOID lpMsgBuf;
   int error_no;
   error_no = GetLastError();
   FormatMessage(
       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
       NULL,
       error_no,
       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
       (LPTSTR) &lpMsgBuf,
       0,
       NULL
   );
   // Display the string.
   fprintf(stderr, "\n%s failed on error %d: ", functionName, error_no);
   fprintf(stderr, (char*)lpMsgBuf);
   // Free the buffer.
   LocalFree( lpMsgBuf );
   //ExitProcess(1);  // terminate the program
}//printError

getpid returns 调用 进程的进程 ID。新创建进程的进程 ID 通过 lpProcessInformation 参数返回,在 dwProcessId 字段中。因此,不要调用 getpid,而是按如下方式更改代码:

printf("Started program 1 with pid = %i", pi.dwProcessId);

至于putenv,也是修改了调用进程的环境。在 Windows 上,它也只更改 CRT 的环境副本,而不是真正的进程环境。要更改进程环境,您应使用 SetEnvironmentVariable。只要CreateProcesslpEnvironment设置为NULL.

,child就会继承parent的进程环境

总而言之,实现您想要的最简单方法是在程序开始时简单地在您的进程上设置 PROMPT=... 环境:

SetEnvironmentVariableA("PROMPT", "Speak$sUp:$G");

然后让 children 在 CreateProcess.

中不做任何特殊的事情来继承它