开发者

Process name missing from GetCommandLine()

I have a problem with the GetCommandLine() API.

It usually returns the executable name followed by a space and arguments. As documentation says, the first token may not have the complete path to the image and blah blah blah.

I never had problems until now that I used CreateProcess with lpApplicationName not NULL.

If I use:

CreateProcess(NULL, "\"c:\\myexe.exe\" param1 param2", ...)

GetCommandLine returns "c:\myexe.exe param1 param2" as expected.

But if I use:

CreateProcess("C:\myexe.exe", "param1 param2")

GetCommandLine returns only "param1 param2".

How do I know if the executable name is given on the command line if another application launches mine?

Also, MFC startup code assumes that the first开发者_如何学编程 token on the command line is the executable name and skips it. But if you launch a MFC application with the second CreateProcess API example, MFC's code will skip the first argument.


Not your problem. It's the job of the other application to construct the command line properly. You should simply assume that the first argument is an executable name as expected and skip over it.


I have a workaround which can be helpful in a case like this. I guess we always be able to check how our module was been started. In this case we should check first argument.

I will write code because I have some problem with English. Here two ways:

The first case. we can compare module name with first command line argument. something like this:

const TCHAR* csCommandLine = ::GetCommandLine();

// Attention!!! the first symbol can be quete

if (*csCommandLine == _T('\"'))
    csCommandLine++;

TCHAR sModuleFileName[MAX_PATH];

DWORD dwModuleFileName = ::GetModuleFileName(NULL, sModuleFileName, MAX_PATH);

if (dwModuleFileName && !_tcsncmp(csCommandLine, sModuleFileName, dwModuleFileName)) {

    // The command line contains the module name.
}

The second case. we can try to get file attributes for the first command line argument something like this:

// Attention!!! don't use it case if you are going to pass a file path in command line arguments.

int nArgc;

LPTSTR* szArglist = ::CommandLineToArgvW(::GetCommandLine(), &nArgc);

if (nArgc && ::GetFileAttributes(szArglist[0]) != INVALID_FILE_ATTRIBUTES) {

    // The command line contains the module name.
}

::LocalFree(szArglist);

I hope it can be helpful someone.

Regards, Vladimir

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜