CommandLineToArgvW怪癖

时间:2019-04-05 22:54:09

标签: windows winapi

我有一个win32程序,它用给定的CommandLineToArgvW调用lpCmdLine

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
  (void)hInstance;
  (void)hPrevInstance;
  (void)nCmdShow;
  int argc;
  LPTSTR* argv =  CommandLineToArgvW(lpCmdLine, &argc);
  MessageBoxW(0, lpCmdLine, TEXT("lpCmdLine"), MB_OK    );

  for(int i=0; i<argc;++i){
    MessageBoxW(0, argv[i], TEXT("argv"), MB_OK );
  }
  return 0;
}

我观察到的奇怪的事情是:

  • 如果我不带参数调用程序,则lpCmdLine是一个空字符串,而CommandLineToArgvW返回1个参数-可执行路径。
  • 如果使用参数调用,CommandLineToArgvW将返回确切数量的参数,而不包含可执行文件

我找不到记录的这种奇怪行为。

我想念什么?我是否会意外使用该命令?

1 个答案:

答案 0 :(得分:2)

这是记录的行为。

CommandLineToArgvW()

  

printf

     

类型:lpCmdLine

     

指向包含完整命令行的以空终止的Unicode字符串的指针。 如果此参数为空字符串,函数将返回当前可执行文件的路径。

这意味着LPCWSTR仅在CommandLineToArgvW()参数为null或明确地包含可执行文件名称的情况下才返回调用可执行文件的名称。

请注意,lpCmdLine需要完整的命令行。但是,根据WinMain()

  

CommandLineToArgvW()

     

类型:lpCmdLine

     

应用程序的命令行,不包括程序名称。要检索整个命令行,请使用GetCommandLine函数。

因此,当您执行不带参数的程序时,LPSTR的{​​{1}}参数为空白,而WinMain仅返回可执行文件名称。但是,如果使用参数执行程序,则lpCmdLine参数不是空白,但不包含可执行文件名称,因此CommandLineToArgvW()仅返回没有可执行文件名称的参数。

这样,您需要按照lpCmdLine文档的说明进行操作,并使用CommandLineToArgvW()而不是WinMain()GetCommandLine()文档中也对此进行了说明:

  

GetCommandLineW函数可用于获取适合用作lpCmdLine参数的命令行字符串。

因此,请改用它:

CommandLineToArgvW()