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

Installation 如何使用自定义操作在WiX中运行脚本-最简单的示例?,installation,wix,windows-installer,Installation,Wix,Windows Installer,新手WiX问题:我如何 1.将一次性shell脚本与安装程序一起复制到temp中 e、 g 二,。在安装结束时查找并运行该脚本。 e、 g 我想我至少有三个问题: 我找不到permissions.cmd来运行它-我需要[TEMPDIR]permissions.cmd还是什么 在安装程序之前,我的序列来得太早 我需要cmd/c权限。cmd在这里的某个地方,可能靠近execomand 在本例中,permissions.cmd使用cacls.exe将具有写入权限的交互式用户添加到%Prog

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


二,。在安装结束时查找并运行该脚本。
e、 g


我想我至少有三个问题:

  • 我找不到permissions.cmd来运行它-我需要[TEMPDIR]permissions.cmd还是什么
  • 在安装程序之前,我的序列来得太早
  • 我需要cmd/c权限。cmd在这里的某个地方,可能靠近execomand
在本例中,permissions.cmd使用cacls.exe将具有写入权限的交互式用户添加到%ProgramFiles%\VendorACL。我还可以使用secureObject——这个问题是

当我想了解WiX中的CustomActions时,我发现这篇博文很有帮助

您还可以在中找到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>

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

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

这是覆盖还是仅编辑文件夹的ACL

根据该文件,它覆盖了:

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


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

您有没有关于如何使用它的示例?我的意思是,是否使用嵌套在我要更改其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>

等
等
等

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

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

您需要CA在延迟序列中设置权限,因为文件在延迟序列的中途才存在。因此,之前的任何事情都将失败

  • 您的安装程序处于即时状态(因此将失败)
  • 您的设置顺序为1(不可能延迟,因此将失败)
  • 您需要添加一个属性
    Execute=“Deferred”
    ,并将序列从“1”更改为:

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

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

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

    
    

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

    您的示例看起来不错。CreateFolder元素是Component元素的子元素,而Component元素又是Directory元素的子元素。将为此目录设置权限。
    <CreateFolder>
      <Permission User='INTERACTIVE' GenericRead='yes' GenericWrite='yes' 
                  GenericExecute='yes' Delete='yes' DeleteChild='yes' />
      <Permission User='Administrators' GenericAll='yes' />
    </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>
    
    <Custom Action="CallCmd" Execute="Deferred" Before="InstallFinalize" />
    
    <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>