CreateProcess usage for executable wrapper for Windows?

自闭症网瘾萝莉.ら 提交于 2019-12-04 16:47:05

Should be reasonably straightforward.

BOOL WINAPI CreateProcess(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
  _In_        BOOL                  bInheritHandles,
  _In_        DWORD                 dwCreationFlags,
  _In_opt_    LPVOID                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,
  _In_        LPSTARTUPINFO         lpStartupInfo,
  _Out_       LPPROCESS_INFORMATION lpProcessInformation
);

Let's take it in order.

  • lpApplicationName - if you have the full path to the executable you want to run, put it here. That ensures that you get the executable you were expecting, even if another executable with the same name is on the PATH.

  • lpCommandLine - the first element is the executable name. If you've specified lpApplicationName this doesn't need to be fully qualified, or even be the executable's actual name, but it does need to be present. This must be a writable buffer, it cannot be a constant string.

If your extra arguments can go at the end of the command line, this is easy:

wchar_t buffer[1024];
wcscpy_s(buffer, _countof(buffer), GetCommandLine());
wcscat_s(buffer, _countof(buffer), L" -switch1 -switch2");

Otherwise, you'll need to parse the command line to find the right place to insert the arguments, something like this:

while (*lpCmdLine == L' ') lpCmdLine++;
while (ch = *lpCmdLine) 
{
    if (ch == L'"') for (lpCmdLine++; ch = *lpCmdLine; lpCmdLine++) if (ch == L'"') break;
    if (ch == L' ') break;
    lpCmdLine++;
}
while (*lpCmdLine == L' ') lpCmdLine++;
  • lpProcessAttributes and lpThreadAttributes - NULL.

  • bInheritHandles - TRUE, since you want the child to inherit the standard handles.

  • dwCreationFlags - none needed in your scenario, so 0.

  • lpEnvironment - NULL to pass the current environment. In some situations you'd want to explicitly construct a new environment, or a modified copy of your environment, but since your process exists only to launch the child that shouldn't be necessary.

  • lpCurrentDirectory - NULL to inherit your current directory.

  • lpStartupInfo - call GetStartupInfo to fill this out with the same settings as the current process, or just leave it empty as in the code you posted.

  • lpProcessInformation - this is an output parameter, used as shown in your code. In your scenario, where one application is standing in for another, you might want to keep the process handle and use it to wait for the child process to exit before exiting yourself. (This isn't necessary if you know that your parent won't get confused if you exit before your child does.)

You don't need to do anything special about the standard handles, apart from ensuring that bInheritHandles is set. The default is for the child to keep the same standard handles as the parent.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!