使用批处理文件为Wix生成Guids依赖项

时间:2017-01-04 23:11:07

标签: batch-file visual-studio-2015 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而不是Program Files上安装。所以我将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

而不是其他两行,但我没有得到变量

的guid

我知道它没有到达那里因为我在变量中添加了一个回声,并且还使用Guid =&#34;&#34;生成了%OUTPUTFILE%。 (只是一个空字符串/变量)。任何想法为什么它不能得到变量的指导?

1 个答案:

答案 0 :(得分:1)

  

这是我们的老朋友delayed expansion问题。

有很多关于块内变量扩展的问题。

当命令处理器找到一个块(括号之间的任何内容)时,完全解析它并将变量扩展到它们在计算块时所具有的值。如果更新块中的变量值,则需要为变量启用延迟扩展以反映所做的更改。此外,您必须将var语法从%var%更改为!var!

在您的代码中,aGUID var在for块中生成,因此它会在块开始时扩展到它保存的值(在您的情况下为emptyundefined)。要在for块的每次迭代中更新值,您需要启用延迟扩展。

另一种解决方法是使用新的for循环来获取uuidgen.exe的输出,因为for变量始终是内联扩展的。这种方法为您带来了另一个好处,您不需要临时文件。

  

注意:另外,您正在向文件写入多行,请注意

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

仅打开文件一次,而

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

随时打开和关闭文件&gt;&gt;&#34;%output%&#34;使用重定向,所以第一个加速块。

  

顺便说一句

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

相同
(
   for ... do (
     ...
   )
)>"%output%"  

最后,其最佳做法包含在var namevar 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

的原因