首页 > 解决方案 > 如何将命令行参数逐字传递给 QProcess?

问题描述

如何将当前进程的命令行参数传递给 a QProcess,理想情况下避免任何转换?即,传递给当前进程的任何“垃圾”都应该传递给子进程,而不会影响char*,wchar_tQString.

这个问题的动机是这个答案

标签: qtcommand-line-argumentsqprocess

解决方案


视窗

返回的本机命令行是以可执行名称/路径开头GetCommandLine()的数组。具有在 Windows 上可用的方法,并且该方法可用于附加命令行的参数部分。然后主要的工作是解析命令行以找到参数的开头:wchar_tQProcesssetNativeArguments

QString getWindowsCommandLineArguments() {
   const wchar_t *args = GetCommandLine();
   bool oddBackslash = false, quoted = false, whitespace = false;
   // skip the executable name according to Windows command line parsing rules
   while (auto c = *args) {
      if (c == L'\\')
         oddBackslash ^= 1;
      else if (c == L'"')
         quoted ^= !oddBackslash;
      else if (c == L' ' || c == L'\t')
         whitespace = !quoted;
      else if (whitespace)
         break;
      else
         oddBackslash = false;
      args++;
   }
   return QString::fromRawData(reinterpret_cast<const QChar*>(args), lstrlen(args));
}

然后:

QProcess process;
process.setNativeArguments(getWindowsCommandLineArguments());

其他平台

等价于setNativeArguments在其他平台上不可用,因此我们能做的最好的事情就是通过QString往返传递参数。只要参数在当前的 8 位编码中有效,这将正常工作。参数必须在 的开头捕获main,因为 Qt 可能会删除它自己解释的参数:

QStringList &setProcessArguments() {
   static QStringList args;
   return args;
} 
const QStringList &processArguments() { return setProcessArguments(); }
int main(int argc, char **argv) {
   setProcessArguments().reserve(argc-1);
   for (int i = 1; i < argc; ++i)
      setProcessArguments().append(QString::fromLocal8Bit(argv[i]));

   QCoreApplication app{argc, argv}; // may modify argc, argv
   ...
}

QProcess process;
process.setArguments(processArguments());

推荐阅读