Почему QProcess конвертирует '=' в моих аргументах в пробелы - PullRequest
0 голосов
/ 12 июня 2010

Я столкнулся со странной ошибкой при запуске программы Qt в Windows. Программа использует QProcess для порождения дочернего процесса с двумя аргументами. Программа и аргументы, передаваемые методу QProcess :: start (), имеют вид:

"batchfile.bat" "--option1=some_value" "--option2=some_other_value\with_a\path"

По какой-то причине, когда эти опции попадают в пакетный файл для обработки, знаки равенства были преобразованы в пробелы, и теперь это выглядит так:

"batchfile.bat" "--option1 some_value" "--option2 some_other_value\with_a\path"

из-за этого обработка не выполняется. Любые идеи, что может быть причиной замены знаков равенства пробелами? Я использую сборку mingw инфраструктуры QT 4.6.3, которая находится на странице загрузки Qt.

EDIT: Вот фактический код. Я не писал это (я полный нуб Qt), но я должен попытаться заставить это работать. Это часть автоматизированной системы сборки, которая работает на двух версиях RHEL (4 и 5), OS X и Windows. И он отлично работает везде, кроме Windows.

QProcess sconsProcess;
sconsProcess.setWorkingDirectory(build.getBuildLocation());
sconsProcess.setProcessChannelMode(QProcess::MergedChannels);

qDebug()<<"Starting scons process:"<<build.getSconsLocation()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()<<"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString());
sconsProcess.start(build.getSconsLocation(), QStringList()<<QString("--variant=%1-%2").arg(build.getOs()).arg(build.getVariant())<<
          QString("--source-release=%1").arg(build.getSettings().getSetting("sourceReleaseLocation", QStringList()"BUILDLOCATION"<<"VERSION",
                    QStringList()<<build.getBuildLocation()<<build.getBuildPackage().getVersion()).toString()));
qDebug()<<"Source release build process started";

Значения actaul, которые переводятся в Windows (бит, который выводится при первом вызове qDebug ()):

ОТЛАДКА: Запуск процесса scons: "V: \ Glast_Software \ Toaster \ tools \ Python2.5 \ Scripts \ scons-1.3.0.bat" "--variant = Windows-i386-32bit-vc71-Debug" "- -source-release = V: \ Glast_Software \ Toaster \ ReleaseManagerBuild \ Windows-i386-32bit-vc71 \ Debug \ ScienceTools \ LATEST-1-3163 \ ScienceTools-LATEST-1-3163-source.zip "

Однако внутри scons-1.3.0.bat (у меня было так, что он повторял все выполненные команды) переданные параметры выглядят так:

"- вариант Windows-i386-32bit-vc71-Debug" "- source-release V: \ Glast_Software \ Toaster \ ReleaseManagerBuild \ Windows-i386-32bit-vc71 \ Debug \ ScienceTools \ LATEST-1-3163 \ ScienceTools-LATEST-1-3163-source.zip "

с пропущенными знаками равенства.

РЕДАКТИРОВАТЬ (29.06.10) : Я должен добавить, что эта система предназначена для запуска в небольшой пакетной ферме Windows с использованием системы очередей LSF. Сбой происходит только тогда, когда процесс выполняется как пакетное задание. Когда я запускаю эту программу из командной строки на одном из пакетных компьютеров, она отлично работает и выполняет именно то, что должна. Так что, возможно, это проблема окружающей среды.

Ответы [ 2 ]

0 голосов
/ 12 июня 2010

Есть большая вероятность, что это происходит из-за того, что кавычки не проходят через них (возможно, их необходимо экранировать, см. Документы для QProcess :: start () ).

cmd.exe обрабатывает знаки равенства в параметрах командной строки, которые не заключаются в кавычки в качестве аргументов, похожих на пробел или табуляцию. Просто одна из многих странностей в сценариях Windows cmd:

C:\test>type c:\util\cmdechoargs.cmd
@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo argv[%i%]: %1
set /a i=%i% + 1
shift
goto :loop


C:\test>cmdechoargs testing=123
args[*]: testing=123
argv[0]: testing
argv[1]: 123

C:\test>cmdechoargs "testing=123"
args[*]: "testing=123"
argv[0]: "testing=123"

Лучшая документация для обработки аргументов командной строки в сценариях Windows cmd: "Сценарии оболочки Windows NT" Тима Хилла - используйте ее всего за копейки!

Основываясь на примерах, приведенных в вашем обновлении, я думаю, что вы можете захотеть, чтобы в ваших опциях с символами равенства были заключены кавычки:

"\"--variant=%1-%2\""
"\"--source-release=%1\""

Редактировать - новый материал

В следующем скрипте есть подпрограмма, которая удаляет кавычки аргумента, переданного в скрипт cmd. Процедура возвращает аргумент «dequoted» в переменной окружения с именем RET, используя идиому / технику из книги Тима Хилла, о которой я упоминал выше. Я украл часть кода для удаления квотирования из примера здесь: http://ss64.com/nt/syntax-esc.html,, но сделал его немного более устойчивым для обработки пустых кавычек.

@echo off
setlocal
set /a i=0
echo args[*]: %*
:loop
if {%1} == {} goto :eof
echo.
echo argv[%i%]: %1

call :dequote %1
set dequoted_arg=%RET%
echo argv[%i%] ^(dequoted^): %dequoted_arg%

set /a i=%i% + 1
shift
goto :loop


:dequote
setlocal
SET _string=###%1###
if {%_string%} == {######} goto :dequote_empty
if {%_string%} == {###""###} goto :dequote_empty
SET _string=%_string:"###=%
SET _string=%_string:###"=%
SET _string=%_string:###=%
goto :dequote_done

:dequote_empty
set _string=

:dequote_done
endlocal & (set RET=%_string%) & goto :eof

Такого рода вещи почему вы хотите избегать (на мой взгляд) сценариев cmd, за исключением самых простых задач. Но я надеюсь, что это поможет вам передать аргументы без кавычек процессу scons через ваш пакетный файл.

0 голосов
/ 12 июня 2010

Вы пытались избежать знаков =?Кроме того, пути в вашем примере обязательно должны экранироваться символом \.

...