Пакетный сценарий и визуальная студия предварительной сборки
У меня есть пакетный скрипт, который в основном выполняет некоторую замену строк на основе конфигураций на этапе предварительной сборки для Visual Studio. Пакетный скрипт работает нормально, когда я запускаю его из cmd. Но если я запускаю его из предварительной сборки VS, следующая строка не оценивает%replaceStr% и%version% как значения переменных. Я даже попытался повторить эти 2, и они не оцениваются как переменные.
if NOT "!line!" == "" call set "line=!line:%replaceStr%=%version%!"
! ReplaceStr! и! версия! Это нормально, хотя (через эхо, я не думаю, что могу использовать! в! для замены строки.
Это может быть причиной сбоя при запуске из команд предварительной сборки VS, но работает нормально, когда я запускаю из cmd. Я даже добавил C:\windows\system32\cmd /c в предварительную сборку и все еще не работает. Какие-нибудь мысли?
Спасибо!
2 ответа
Где вы устанавливаете переменные. Каждый процесс получает копию среды своего родителя. Но вы не можете влиять на среду вашего родительского процесса только на дочерние процессы во время их запуска и на свои собственные.
Пакетные файлы используют cmd.exe, который они запускают в среде. Это единственный случай, когда программа влияет на родительскую среду.
Среда одного cmd отделена от среды другого.
И из комплекта для разработки программного обеспечения Windows Vista
Переменные среды Каждый процесс имеет блок среды, который содержит набор переменных среды и их значений. Командный процессор предоставляет команду set для отображения своего блока среды или для создания новых переменных среды. Программы, запускаемые командным процессором, наследуют переменные окружения командного процессора.
По умолчанию дочерний процесс наследует переменные среды своего родительского процесса. Однако вы можете указать другую среду для дочернего процесса, создав новый блок среды и передав указатель на него в качестве параметра функции CreateProcess.
Каждый блок среды содержит переменные среды в следующем формате:
Var1=Value1\0
Var2=Value2\0
Var3=Value3\0
...
VarN=ValueN\0\0
Имя переменной среды не может включать знак равенства (=). Общий размер блока среды для процесса не может превышать 32 767 символов.
Функция GetEnvironmentStrings возвращает указатель на блок среды вызывающего процесса. Это следует рассматривать как блок только для чтения; не изменяйте это напрямую. Вместо этого используйте функцию SetEnvironmentVariable, чтобы изменить переменную среды. Когда вы закончите работу с блоком среды, полученным из GetEnvironmentStrings, вызовите функцию FreeEnvironmentStrings, чтобы освободить блок.
Вызов SetEnvironmentVariable не влияет на системные переменные среды. Пользователь может добавлять или изменять системные переменные среды с помощью панели управления. Чтобы программно добавить или изменить системные переменные среды, добавьте их в раздел реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment, а затем отправьте сообщение WM_SETTINGCHANGE с параметром lParam для строки "Environment". Это позволяет приложениям, таким как оболочка, забирать ваши обновления. Обратите внимание, что значения переменных среды, перечисленных в этом ключе, ограничены 1024 символами.
Функция GetEnvironmentVariable определяет, определена ли указанная переменная в среде вызывающего процесса и, если да, каково ее значение.
Похоже:
Даже из командной строки ваш командный файл не работает.
Я предполагаю, что в первый раз это не удается, но потом это работает.
Если это так, то ваш код находится внутри блока скобок.
Возможно, ваш код выглядит так
if %a%==%b% (
set version=%a%
if NOT "!line!" == "" call set "line=!line:%replaceStr%=%version%!"
)
Это влияние времени расширения процентных переменных, они расширяются, когда анализируется весь блок, но ни одна из строк не выполняется в это время.
Итак %version%
расширяется до нуля (для первого запуска), но следующий запуск будет расширяться правильно.
Чтобы избежать этого, вы можете использовать различную технику, в зависимости от того, насколько проблематичен ваш контент.
call set "line=%%line:!replaceStr!=!version!%%"
Парсер расширяет эту строку два раза, сначала восклицательные знаки расширяются, а затем вызов расширяет %line:rep=ver%
,
Это работает, если ваша строка не содержит критических специальных символов, таких как каретки ^
, проценты или цитаты.