如何使用自定义操作在WiX中运行脚本 - 最简单的示例?

时间:2008-10-04 11:09:06

标签: installer wix windows-installer

新手WiX问题:我如何处理 1.将一次性shell脚本与安装程序一起复制到temp 例如

  <Binary Id='permissions.cmd' src='permissions.cmd'/>  

2。在安装结束时查找并运行该脚本 例如

<CustomAction Id='SetFolderPermissions' BinaryKey='permissions.cmd' 
    ExeCommand='permissions.cmd' Return='ignore'/>  

<InstallExecuteSequence>
    <Custom Action="SetFolderPermissions" Sequence='1'/>
</InstallExecuteSequence>  

我认为我至少有三个问题:

  • 我找不到 permissions.cmd 来运行它 - 我需要 [TEMPDIR] permissions.cmd 还是什么?
  • 我的序列在安装程序之前就太早了。
  • 我在这里的某处需要 cmd / c permissions.cmd ,可能在 ExeCommand 附近?

在此示例中, permissions.cmd 使用 cacls.exe 将具有写入权限的交互式用户添加到%ProgramFiles%\ Vendor ACL 。我还可以使用 secureObject - 该问题是 "How do I add the interactive user to a directory in a localized Windows"?

5 个答案:

答案 0 :(得分:5)

这是一个工作示例(用于设置权限,而不是用于运行脚本):

<Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="ProgramFilesFolder" Name="PFiles">
    <Directory Id="BaseDir" Name="MyCo">
      <Directory Id="INSTALLDIR" Name="MyApp" LongName="MyProd">

        <!-- Create the folder, so that ACLs can be set to NetworkService -->
        <Component Id="TheDestFolder" Guid="{333374B0-FFFF-4F9F-8CB1-D9737F658D51}"
                   DiskId="1"  KeyPath="yes">
          <CreateFolder Directory="INSTALLDIR">
            <Permission User="NetworkService"
                        Extended="yes"
                        Delete="yes"
                        GenericAll="yes">
            </Permission>
          </CreateFolder>
        </Component>

      </Directory>
    </Directory>
  </Directory>
</Directory>

请注意,这是在Permission标记中使用'Extended =“Yes”',因此它使用SecureObjects表和自定义操作而不是LockPermissions表(请参阅WiX docs for Permission Element)。在此示例中,SecureObjects应用于MyProd目录的权限由子目录继承,而使用LockPermissions时则不然。

答案 1 :(得分:4)

当我想了解WiX中的CustomActions时,我发现博客帖子 From MSI to WiX, Part 5 - Custom actions: Introduction 很有帮助。

您还可以在 CustomAction Element 中找到CustomAction及其属性的定义。

你需要做这样的事情

<CustomAction Id="CallCmd" Value="[SystemFolder]cmd.exe" />
<CustomAction Id="RunCmd"  ExeCommand="/c permission.cmd" />
<InstallExecuteSequence>
    <Custom Action="CallCmd" After="InstallInitialize" />
    <Custom Action="RunCmd" After="CallCmd" />
</InstallExecuteSequence>

答案 2 :(得分:2)

您可以尝试使用Permission element作为CreateFolder元素的子元素,而不是运行自定义操作,例如:

<CreateFolder>
  <Permission User='INTERACTIVE' GenericRead='yes' GenericWrite='yes' 
              GenericExecute='yes' Delete='yes' DeleteChild='yes' />
  <Permission User='Administrators' GenericAll='yes' />
</CreateFolder>
  

这会覆盖还是只编辑文件夹的ACL?

根据MSDN documentation覆盖:

  

LockPermissions表中列出的每个文件,注册表项或目录都会收到一个显式安全描述符,无论它是否替换现有对象。

我刚刚确认通过在Windows 2000上运行测试安装。

答案 3 :(得分:2)

你有一个如何使用它的例子吗?我的意思是,在我想要更改其ACL的目录下使用 CreateFolder 嵌套吗?或者我首先单独使用 CreateFolder ?以下是否接近?

<Wix xmlns="http://schemas.microsoft.com/wix/2003/01/wi">
<Fragment>
  <DirectoryRef Id="TARGETDIR">
    <Directory Id='ProgramFilesFolder' Name='PFiles'>
      <Directory Id="directory0" Name="MyApp" LongName="My Application">
        <Component Id="component0" DiskId="1" Guid="AABBCCDD-EEFF-1122-3344-556677889900">

          <CreateFolder>
            <Permission User='INTERACTIVE' 
              GenericRead='yes' 
              GenericWrite='yes' 
              GenericExecute='yes' 
              Delete='yes' 
              DeleteChild='yes' />
            <Permission User='Administrators' GenericAll='yes' />
          </CreateFolder>

          <File Id="file0" Name="myapp.exe" Vital="yes" Source="myapp.exe">
            <Shortcut Id="StartMenuIcon" Directory="ProgramMenuFolder" Name="MyApp" LongName="My Application" />
          </File>
        </Component>
      <Directory Id="directory1" Name="SubDir" LongName="Sub Directory 1">
        <Component Id="component1" DiskId="1" Guid="A9B4D6FD-B67A-40b1-B518-A39F1D145FF8">
          etc...
          etc...
          etc...
        </Component>
      </Directory>
    </Directory>
  </DirectoryRef>
</Fragment>

答案 4 :(得分:1)

大多数人倾向于避开lockPermissions表,因为它不是附加的,这意味着它将覆盖您当前的权限(从托管环境的角度来看,这很糟糕)。我建议你使用支持ACL继承的工具,例如SUBINACL或SETACL或许多ACL工具之一。

关于您之前的帖子失败的原因,有几个原因。您可以在四个位置放置自定义操作(CA):UI,立即,延迟和提交/回滚。

您需要CA在延迟序列中设置权限,因为文件直到延迟序列的中途才会出现。因此,任何事先都会失败。

  1. 您的设置即时(因此会失败)
  2. 您的设置顺序为1(无法延迟,因此会失败)
  3. 您需要添加Execute="Deferred"属性并将序列从“1”更改为:

    <Custom Action="CallCmd" Execute="Deferred" Before="InstallFinalize" />
    

    这将确保在安装文件之后,但在延迟阶段结束之前(所需位置)完成。

    我还建议您直接调用EXE文件而不是批处理文件。安装程序服务将直接在您需要的上下文中启动和EXE文件。使用批处理文件将在正确的上下文中启动批处理文件,并可能在执行时丢失不需要的帐户的上下文。