微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决使用 putenv 和 getpid 在 C 中使用 CreateProcess 获取错误

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

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() 返回一个 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],"%s\\cmd.exe",sysLoc);
   snprintf(lpCommandLine[3],"%s\\nslookup.exe",sysLoc);
   snprintf(lpCommandLine[4],"%s\\charmap.exe",sysLoc);
   snprintf(lpCommandLine[5],"%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,FALSE,&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],&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],&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],&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,error_no,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),// Default language
       (LPTSTR) &lpMsgBuf,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 返回调用进程的进程 ID。新创建进程的进程 ID 通过 lpProcessInformation 参数在 dwProcessId 字段中返回。因此,不要调用 getpid,而是按如下方式更改您的代码:

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

至于 putenv,它还修改了调用过程的环境。在 Windows 上,它也只会更改 CRT 的环境副本,而不是真正的进程环境。要更改流程环境,您应使用 SetEnvironmentVariable。只要 lpEnvironmentCreateProcess 设置为 NULL,子进程将继承父进程环境。

综上所述,实现您想要的最简单方法是在程序开始时简单地在您的进程中设置 PROMPT=... 环境:

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

然后让孩子通过在 CreateProcess 中不做任何特别的事情来继承它。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。