Wix延迟自定义操作访问被拒绝

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Wix延迟自定义操作访问被拒绝相关的知识,希望对你有一定的参考价值。

背景:客户已更改应用程序的名称。应用程序已将文件存储在AppData文件夹下,现在该文件夹需要复制到新名称(并删除旧名称)。

我有Wix 3.6的MSI安装版本。我没有找到复制文件夹(只有文件)的标准方法。所以我一直在尝试使用xcopy命令进行自定义操作,但这似乎很难。

如果我立即建立CA并在InstallFinalize之后安排它,这适用于WinXP,但只能通过运行MSI作为管理员在Win7上运行。

如果我进行延期CA,则会出现拒绝访问错误。即使我测试要复制到用户文件夹下的文件夹,也会出现此错误。但是,如果我使用echo命令测试延迟的CA会成功。

<CustomAction Id="CopyFolder_PropertyAssign" Property="CopyFolder" 
 Value="&quot;[SystemFolder]cmd.exe&quot; /c xcopy 
        &quot;[$(var.PlatformCommonAppDataFolder)]OldName&quot; 
        &quot;[$(var.PlatformCommonAppDataFolder)]NewName&quot; 
        /s /i /h /k /o /y" />
<CustomAction Id="CopyFolder" BinaryKey="WixCA" DllEntry="CAQuietExec" 
 Execute="deferred" Return="check" Impersonate="no" />

<Custom Action="CopyFolder_PropertyAssign" Before="InstallFinalize"></Custom>
<Custom Action="CopyFolder" After="CopyFolder_PropertyAssign"></Custom>

CAQuietExec:  Access denied
CAQuietExec:  Error 0x80070004: Command line returned an error.
CAQuietExec:  Error 0x80070004: CAQuietExec Failed

除了访问被拒绝之外,必须有其他的东西,因为在用户文件夹下也会发生同样的事情,但这是什么地球?

或者是否有其他解决方案(除了创建exe包)?

编辑:

该文件夹位于所有用户AppData下。

编辑:

这似乎是不可能的。选择的解决方法是立即创建CA并引导用户以管理员身份启动安装程序(或者在大多数情况下应该是这种情况)。无论如何,谢谢你的帮助!

答案

延迟的自定义操作副本到AppDataFolder可能会失败,因为您正在运行延迟和系统帐户,因此它正在尝试访问用户的系统帐户的AppDataFolder。请注意,0x80070004未被拒绝访问,它是“系统无法打开文件”。

直接CA将失败,因为默认情况下这些CA未升级,因此显然访问需要提升。

这个问题的通常解决方案是使用CopyFile元素。使用这些位置的目录定义将文件从旧位置复制到新位置。如果将delete设置为yes,它将移动文件,从旧位置删除它们。

正如Stein所指出的,当新版本首次运行时,应该由应用程序完成。数据迁移确实是应用程序问题,应该在应用程序中解决,而不是通过重载安装。除了您遇到的困难之外,如果安装失败并回滚(恢复已删除的文件?)以及可能还有其他无法预料的文件,也存在潜在的问题。

另一答案

应用程序启动顺序:如果这些是userprofile files - 换句话说,应用程序的启动用户可写 - 那么在应用程序启动序列中进行此清理要好得多。 Crucially this will make the operation run for every users, and not just the user installing the setup。忘记为盒子上的所有用户重命名是一个常见的错误。这假设这些是每用户文件(每个用户的副本),而不是%ALLUSERSPROFILE%中所有用户的共享文件(仅对管理员用户可写)。

MSI复杂性:请不要在设置中执行此操作。 MSI非常复杂,具有模拟和运行时行为 - 这就是导致您看到的神秘错误消息的原因。如果可以在应用程序启动序列中使用用户权限,则完全没有理由在设置中执行此操作。您只需在启动应用程序时重命名该文件夹,应该这样做吗?与自定义操作(尤其是延迟模式自定义操作)相比,应用程序启动代码更容易实现并且更加容易调试。如果需要,您还可以提供交互式错误消息(与写入日志的错误相反 - 或根本没有日志)。

实现:显然要注意引入应用程序启动代码错误,一旦为相关用户重命名,可能在注册表中设置一个标志 - 以便禁止此重命名操作多次运行。漫游配置文件可能会导致问题,请确保将操作设置为每台计算机运行一次 - 至少。您还可以将标志写入appdata文件夹层次结构的非漫游部分吗?那可能更好。当然,事实上。应该不会引发漫游问题。

挑战:只是几个挑战:

  • Locks?应用程序启动时是否会有任何文件/文件夹锁定?也许?捕获异常,通知用户,关闭并重试?拒绝发布,直到重命名可能发生?是否可以接受?
  • Old application launch?:这很重要吗?有些人尝试象征性的联系 - 我的两分钱 - 他们是魔鬼的工作:-)。我想问题是,如果旧应用程序找不到它的文件会发生什么?它甚至推出了吗?第二个问题是:在“清理”之后,旧应用程序无法正常工作是否重要?

以上是关于Wix延迟自定义操作访问被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

将动态属性传递给延迟的自定义操作 WIX

wix 自定义操作,管理员组

Wix Bootstrapper 清单或提升的自定义操作

蜡烛.exe 访问被拒绝

Wix - 自定义操作返回代码 - 处理

向 WiX 安装程序添加自定义操作