如何解决使用 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
。只要 lpEnvironment
的 CreateProcess
设置为 NULL
,子进程将继承父进程环境。
综上所述,实现您想要的最简单方法是在程序开始时简单地在您的进程中设置 PROMPT=...
环境:
SetEnvironmentVariableA("PROMPT","Speak$sUp:$G");
然后让孩子通过在 CreateProcess
中不做任何特别的事情来继承它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。