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


新手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%\卖方 ACL。我也可以用 secureObject  - 那个问题是 “如何将交互式用户添加到本地化Windows中的目录”? 


1892
2017-10-04 11:09


起源



答案:


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

<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文档)。在此示例中,SecureObjects应用于MyProd目录的权限由子目录继承,而使用LockPermissions时则不是这种情况。


5
2018-01-06 20:15



很酷,我不知道..谢谢+1;) - CheGueVerra


答案:


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

<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文档)。在此示例中,SecureObjects应用于MyProd目录的权限由子目录继承,而使用LockPermissions时则不是这种情况。


5
2018-01-06 20:15



很酷,我不知道..谢谢+1;) - CheGueVerra


我找到了博文 从MSI到WiX,第5部分 - 自定义操作:简介 在我想了解WiX中的CustomActions时很有帮助。

您还可以在中找到CustomAction及其属性的定义 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>

4
2017-10-04 14:23





你有一个如何使用它的例子吗?我的意思是,确实使用 创建文件夹 嵌套  我想要更改其ACL的目录?或者我使用 创建文件夹 首先,分开?以下是否接近?

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


2
2017-10-14 14:04



你的例子看起来正确。 CreateFolder元素是Component元素的子元素,而Component元素又是Directory元素的子元素。权限将设置为此目录。 - Pavel Chuchuva


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

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

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

根据 MSDN文档 它覆盖:

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

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


2
2017-10-13 23:03



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


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

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

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

  1. 您的设置是立即的(因此将失败)
  2. 您的设置顺序为1(无法延迟,因此将失败)

你需要添加一个属性 Execute="Deferred" 并将序列从“1”更改为:

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

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

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


1
2017-10-23 06:57