2017-01-04 3 views
0

У меня есть проект с настройкой Wix, и я пытаюсь найти способ не включать каждую зависимость вручную, как я это делаю, в кучу разных проектов.Создание зависимостей с гидами для 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. 

Получил эту идею из this answer за исключением того, что мне нужно, чтобы добавить GUID, потому что я устанавливаю на Inetpub вместо Программные файлы. Поэтому я включил uuidgen.exe в проект для создания GUID. Я вызываю exe и отсылаю guid в файл temp, который я позже пытался прочитать, за исключением того, что он его не читает. Я пробовал этот подход в другом пакетном файле и вручную вызывал его, и он читал его, поэтому я не знаю, почему он здесь не работает. В основном я говорю об этих двух линий:

%PROJDIR%Uuidgen.Exe> %PROJDIR%temp.txt 
set /p aGUID=<%PROJDIR%temp.txt 

Я удалить удаления, чтобы проверить, что файл генерации GUID и создается, и именно там, так что я знаю, что бы быть вторая линия.

Я также попытался запустить

for /f %%i in ('"%PROJDIR%\Uuidgen.Exe"') do set GUID=%%i 

вместо двух других линий, но я не получаю Guid от переменной

Я знаю, что он не получает там, потому что я добавил эхо с переменной, а также %OUTPUTFILE% генерируется с помощью Guid = "" (только пустая строка/переменная). Любые идеи, почему он не получил руководство по переменной?

+0

'Задержка вопрос expansion'. Я включил ответ о том, как решить эту проблему, не включив ее. Но вы должны уделять пристальное внимание другим сообщениям, поскольку «отложенное расширение» или «переменное расширение внутри блока» было задано много раз. Надеюсь, поможет. – elzooilogico

+0

Почему вы не можете использовать автоматически созданные GUID, либо опуская атрибут guid, либо используя 'Guid =" * "'? Если вы когда-либо автоматически генерируете файл wxs для тех же компонентов снова, вы можете столкнуться с проблемами при обновлении в зависимости от того, где вы планируете removeexistingproducts –

+0

@Brian Sutherland, потому что внешняя мудрая ошибка, я думаю, автоматически создаваемые подсказки работают только в папке программных файлов. Но ваша забота также верна, я не думал об этом сценарии – CPay

ответ

1

Это наш старый друг delayed expansion вопрос.

Существует множество вопросов об изменении переменной внутри блоков.

Когда командный процессор находит блок (что-либо между круглыми скобками), полностью анализирует его и расширяет переменные до значения, которое они имеют при оценке блока. Если вы обновите значение переменной внутри блока, вам нужно включить замедленное расширение для переменной, чтобы отразить сделанные изменения. Также вы должны изменить синтаксис var от %var% до !var!.

В коде aGUID вар генерируется внутри for блока, поэтому он расширяется до значения, которое он держит, когда начинается блок (в вашем случае empty или undefined). Чтобы обновить значение для каждой итерации блока, вам необходимо включить замедленное расширение.

Другим обходным путем является использование нового цикла for для вывода вывода uuidgen.exe, поскольку переменные for всегда расширяются в ряд. Такой подход дает вам еще одно преимущество, вам не понадобится временный файл.

ПРИМЕЧАНИЕ: Кроме того, вы пишете несколько строк в файл, обратите внимание, что

>"%output%" (
    for ... do (
    echo(... 
    echo(... 
    ) 
) 

Открывает файл только один раз, в то время как

for ... do (
    echo(...>>"%output%" 
    echo(...>>"%output%" 
    ) 

открывает и закрывает файл любой time >> «% output%» используется перенаправление, поэтому сначала ускоряется блок.

BTW

>"%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