У меня есть настроенный проект Wix, и я пытаюсь найти способ не включать все зависимости вручную, как это необходимо для множества разных проектов.
Я пытаюсь использовать пакетный файл при предварительной сборке, который выглядит как
@echo off
set TARGETDIRECTORY=%1
set OUTPUTFILE=%2
set PROJDIR=%3
echo Starting Dependency check...
echo ^<?xml version="1.0" encoding="UTF-8"?^> > %OUTPUTFILE%
echo ^<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"^> >> %OUTPUTFILE%
echo ^<Fragment^> >> %OUTPUTFILE%
echo ^<ComponentGroup Id="MyWebApiBinaries" Directory="INSTALLFOLDER"^> >> %OUTPUTFILE%
for %%F in (%TARGETDIRECTORY%\*.dll) do (
echo "-- Adding %%~nxF"
echo "-- Calling %PROJDIR%Uuidgen.Exe"
%PROJDIR%Uuidgen.Exe> %PROJDIR%temp.txt
set /p aGUID=<%PROJDIR%temp.txt
del %PROJDIR%temp.txt
echo "-- Adding %aGUID%"
echo ^<Component Id="%%~nxF" Guid="%aGUID%"^> >> %OUTPUTFILE%
echo ^<File Id="%%~nxF" Name="%%~nxF" Source="%%~dpnxF" Vital="yes" KeyPath="yes" DiskId="1"/^> >> %OUTPUTFILE%
echo ^</Component^> >> %OUTPUTFILE%
)
echo ^</ComponentGroup^> >> %OUTPUTFILE%
echo ^</Fragment^> >> %OUTPUTFILE%
echo ^</Wix^> >> %OUTPUTFILE%
echo Dependency check done.
Получил эту идею из этого ответа, за исключением того, что мне нужно было добавить GUID, потому что я устанавливаю в inetpub вместо программных файлов. Поэтому я включил uuidgen.exe в проект для создания GUID. Я вызываю exe и переключаю guid во временный файл, который позже пытался прочитать, за исключением того, что он его не читает. Я пробовал этот подход в другом командном файле и вручную его вызываю, и он его читает, поэтому я не знаю, почему он здесь не работает. В основном я говорю об этих двух строчках:
%PROJDIR%Uuidgen.Exe> %PROJDIR%temp.txt
set /p aGUID=<%PROJDIR%temp.txt
Я удалил удаление, чтобы убедиться, что файл генерирует guid и создается, и он там, поэтому я знаю, что это должна быть вторая строка.
Я также пробовал бегать
for /f %%i in ('"%PROJDIR%\Uuidgen.Exe"') do set GUID=%%i
Вместо двух других строк, но я не получаю руководство по переменной
Я знаю, что этого не происходит, потому что я добавил эхо с переменной, а также %OUTPUTFILE%
генерируется с Guid = "" (просто пустой строкой / переменной). Есть идеи, почему он не получает руководство по переменной?
1 ответ
Это проблема нашего старого друга
delayed expansion
.
Есть масса вопросов о расширении переменных внутри блоков.
Когда командный процессор находит блок (что-либо в скобках), он полностью анализирует его и расширяет переменные до значения, которое они имеют при оценке блока. Если вы обновляете значение переменной в блоке, вам необходимо включить отложенное расширение для переменной, чтобы отразить внесенные изменения. Также вы должны изменить синтаксис var с %var%
на !var!
.
В вашем коде aGUID
var создается в блоке for
, поэтому он расширяется до значения, которое он содержит, когда начинается блок (в вашем случае empty
или undefined
). Чтобы обновлять значение на каждой итерации блока for, вам необходимо включить отложенное расширение.
Другой обходной путь - использовать новый цикл for
для получения выходных данных uuidgen.exe
, поскольку переменные for
всегда раскрываются в строке. Такой подход дает вам еще одно преимущество: вам не понадобится временный файл.
ПРИМЕЧАНИЕ: Кроме того, вы пишете несколько строк в файл, обратите внимание, что
>"%output%" (
for ... do (
echo(...
echo(...
)
)
Открывает файл только один раз, тогда как
for ... do (
echo(...>>"%output%"
echo(...>>"%output%"
)
Открывает и закрывает файл каждый раз, когда >> используется перенаправление "% output%", поэтому сначала ускоряется блок.
КСТАТИ
>"%output%" (
for ... do (
...
)
)
Такой же как
(
for ... do (
...
)
)>"%output%"
Наконец, рекомендуется заключать в кавычки как var name
, так и var content
, как в
set "TARGETDIRECTORY=%~1"
Чтобы избавиться от нежелательных конечных пробелов, также %~1
означает первый аргумент без кавычек.
Не испытано. Возможный рабочий код
@echo off
SetLocal
set "TARGETDIRECTORY=%~1"
set "OUTPUTFILE=%~2"
set "PROJDIR=%~3"
if not "%TARGETDIRECTORY%" EQU "" if not "%OUTPUTFILE%" EQU "" echo Missing argument/s.& exit/B
if not exist "%PROJDIR%Uuidgen.Exe" echo Uuidgen.exe not found or missing argument.& exit/B
echo Starting Dependency check...
>"%OUTPUTFILE%" (
echo ^<?xml version="1.0" encoding="UTF-8"?^>
echo ^<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"^>
echo ^<Fragment^>
echo ^<ComponentGroup Id="MyWebApiBinaries" Directory="INSTALLFOLDER"^>
for %%F in (%TARGETDIRECTORY%\*.dll) do (
for /F %%U in ('"%PROJDIR%Uuidgen.Exe"') do (
echo "-- Adding %%~nxF - GUID %%U" >CON
echo ^<Component Id="%%~nxF" Guid="%%U"^>
echo ^<File Id="%%~nxF" Name="%%~nxF" Source="%%~dpnxF" Vital="yes" KeyPath="yes" DiskId="1"/^>
echo ^</Component^>
)
)
echo ^</ComponentGroup^>
echo ^</Fragment^>
echo ^</Wix^>
)
echo Dependency check done.
EndLocal
exit /B
Поскольку весь вывод перенаправляется на OUTPUTFILE
, любое сообщение, которое вы хотите отобразить, должно быть затем перенаправлено на стандартный вывод >CON
, поэтому echo "-- Adding %%~nxF - GUID %%U" >CON
Похожие вопросы
Связанные вопросы
Новые вопросы
batch-file
Пакетный файл - это текстовый файл, содержащий серию команд, которые выполняются интерпретатором команд в системах MS-DOS, IBM OS / 2 или Microsoft Windows.
Delayed expansion
проблема. Я включил ответ о том, как решить эту проблему, не включая его. Но вы должны уделять пристальное внимание другим сообщениям, посколькуdelayed expansion
илиvariable expansion within a block
спрашивали множество раз. Надеюсь, это поможет.Guid="*"
? Если вы когда-нибудь снова автоматически создадите файл wxs для тех же компонентов, вы можете столкнуться с проблемами при обновлении в зависимости от того, где вы запланировали удаление существующих продуктов.