当安装程序第二次为 运行 时,Wix 自定义操作显示来自 RunDLL "Access is denied" 的错误对话框

Wix custom action shows a error dialog from RunDLL "Access is denied" when installer is ran a second time

在 Wix 3.14 中创建了一个带有 Visual Studio 扩展名的工具包安装程序。它包含一个自定义操作,用于在本地系统中搜索 Visual Studio 2019 和 2022 的已安装版本。自定义操作使用 Microsoft 的开源示例以托管 C# 编写。用户 运行 第一次使用安装程序时,它将成功完成并且一切正常。如果用户卸载并再次 运行s,他们将从 RunDLL 收到一个错误对话框,指出“启动 [临时文件夹中临时文件的文件路径] 时出现问题”,消息下方是“访问被拒绝”。此安装程序是针对每台机器的,因此安装程序 运行 提升了权限。

Wix 项目使用 WixVSExtension 搜索 VS2019 及其相关文件夹,我的扩展填补了 VS2022 的空白。 WixVSExtension 永远不会失败,它执行类似的功能。

在故障排除中,我已将错误缩小到调用自定义操作的时间。我观察到 msi 在完成后会删除临时文件。起初我以为可能是文件名冲突。我已经使用 ProcMon 观看了它,但没有得到任何明确的结果来指出罪魁祸首。

我试过调试它并进入代码,但它在进入代码之前就失败了。它会 运行 第一次成功的事实告诉我这不是一个明显的编码错误。想知道是否存在某种类型的竞争条件导致此失败。我的问题是有人知道这种情况,或者对我如何追踪抛出此错误的原因有指示吗?

以下是相关内容: 自定义操作定义

<Binary Id="VSLocator" SourceFile="$(env.RD_BINARIES_PATH)\Setup\VSLocator.CA.dll"/>
<CustomAction Id="VSFindInstances2" BinaryKey="VSLocator" DllEntry="VSFindInstances2" Execute="firstSequence"/>

自定义操作调用

<InstallUISequence>
  <Custom Action="VSFindInstances2" After="VSFindInstances"></Custom>
</InstallUISequence>

自定义动作C#代码:

using System;
using System.Runtime.InteropServices;
using Microsoft.Deployment.WindowsInstaller;
using Microsoft.VisualStudio.Setup.Configuration;

namespace VSLocator {
    public class CustomActions {
        private const int REGDB_E_CLASSNOTREG = unchecked((int)0x80040154);

        [CustomAction]
        public static ActionResult VSFindInstances2( Session session ) {
            try {
                session.Log( "VSFindInstances2 Enter" );
                var query = new SetupConfiguration();
                var query2 = (ISetupConfiguration2)query;
                var e = query2.EnumAllInstances();

                var helper = (ISetupHelper)query;

                int fetched;
                var instances = new ISetupInstance[1];
                do {
                    e.Next( 1, instances, out fetched );
                    if ( fetched > 0 ) {
                        PrintInstance( instances[ 0 ], helper, session );
                    }
                }
                while ( fetched > 0 );
            }
            catch ( COMException ex ) when ( ex.HResult == REGDB_E_CLASSNOTREG ) {
                session.Log( "The query API is not registered. Assuming no instances are installed." );
            }
            catch ( Exception ex ) {
                session.Log( $"Error 0x{ex.HResult:x8}: {ex.Message}" );
            }
            return ActionResult.Success;
        }

        private static void PrintInstance( ISetupInstance instance, ISetupHelper helper, Session session ) {
            var instance2 = (ISetupInstance2)instance;
            var state = instance2.GetState();
            session.Log( $"InstanceId: {instance2.GetInstanceId()} ({( state == InstanceState.Complete ? "Complete" : "Incomplete" )})" );


            if ( ( state & InstanceState.Local ) == InstanceState.Local ) {
                var installationVersion = instance.GetInstallationVersion();
                var version = helper.ParseVersion(installationVersion);
                session.Log( $"InstallationVersion: {installationVersion} ({version})" );
                session.Log( $"InstallationPath: {instance2.GetInstallationPath()}" );

                // 32bit only discovery for now, remove this for 64bit too
                var installPath = instance2.GetInstallationPath();

                if ( installPath.Contains("\Program Files (x86)\") ) {
                    if ( installationVersion.StartsWith( "16." ) && string.IsNullOrEmpty( session[ "VS2019_ROOT_FOLDER]" ] ) ) {
                        session[ "VS2019_ROOT_FOLDER" ] = installPath;
                    }
                    if ( installationVersion.StartsWith( "17" ) && string.IsNullOrEmpty( session[ "VS2022_ROOT_FOLDER]" ] ) ) {
                        session[ "VS2022_ROOT_FOLDER" ] = installPath;
                    }
                }
            }
        }
    }
}

这是调用 VSFindInstances 和 VSFindInstances2 的日志部分:

MSI (c) (2C:30) [17:53:54:639]: Doing action: VSFindInstances
Action 17:53:54: VSFindInstances. 
Action start 17:53:54: VSFindInstances.
MSI (c) (2C:30) [17:53:54:648]: Creating MSIHANDLE (1) of type 790542 for thread 21040
MSI (c) (2C:48) [17:53:54:649]: Invoking remote custom action. DLL: C:\Users\ADM-JI~1.COR\AppData\Local\Temp\MSI3E90.tmp, Entrypoint: FindInstances
MSI (c) (2C:84) [17:53:54:651]: Cloaking enabled.
MSI (c) (2C:84) [17:53:54:651]: Attempting to enable all disabled privileges before calling Install on Server
MSI (c) (2C:84) [17:53:54:651]: Connected to service for CA interface.
MSI (c) (2C!18) [17:53:54:772]: Creating MSIHANDLE (2) of type 790541 for thread 35864
MSI (c) (2C!18) [17:53:54:772]: Creating MSIHANDLE (3) of type 790531 for thread 35864
VSFindInstances:  Entering VSFindInstances in C:\Users\ADM-JI~1.COR\AppData\Local\Temp\MSI3E90.tmp, version 3.14.5722.0
MSI (c) (2C!18) [17:53:54:772]: Closing MSIHANDLE (3) of type 790531 for thread 35864
MSI (c) (2C!18) [17:53:54:810]: PROPERTY CHANGE: Adding VS2019_ROOT_FOLDER property. Its value is 'C:\Program Files (x86)\Microsoft Visual Studio19\Enterprise'.
MSI (c) (2C!18) [17:53:54:823]: PROPERTY CHANGE: Adding VS2019_IDE_MODELING_PROJECTSYSTEM_INSTALLED property. Its value is '1'.
MSI (c) (2C!18) [17:53:54:823]: PROPERTY CHANGE: Adding VS2019_IDE_VWD_PROJECTSYSTEM_INSTALLED property. Its value is '1'.
MSI (c) (2C!18) [17:53:54:823]: PROPERTY CHANGE: Adding VS2019_IDE_VSTS_TESTSYSTEM_INSTALLED property. Its value is '1'.
MSI (c) (2C!18) [17:53:54:824]: PROPERTY CHANGE: Adding VS2019_IDE_FSHARP_PROJECTSYSTEM_INSTALLED property. Its value is '1'.
MSI (c) (2C!18) [17:53:54:825]: PROPERTY CHANGE: Adding VS2019_IDE_VB_PROJECTSYSTEM_INSTALLED property. Its value is '1'.
MSI (c) (2C!18) [17:53:54:825]: PROPERTY CHANGE: Adding VS2019_IDE_VCSHARP_PROJECTSYSTEM_INSTALLED property. Its value is '1'.
MSI (c) (2C!18) [17:53:54:826]: Closing MSIHANDLE (2) of type 790541 for thread 35864
MSI (c) (2C:48) [17:53:54:827]: Closing MSIHANDLE (1) of type 790542 for thread 21040
Action ended 17:53:54: VSFindInstances. Return value 1.
MSI (c) (2C:30) [17:53:54:828]: Doing action: VSFindInstances2
Action 17:53:54: VSFindInstances2. 
Action start 17:53:54: VSFindInstances2.
MSI (c) (2C:30) [17:53:54:832]: Creating MSIHANDLE (4) of type 790542 for thread 21040
MSI (c) (2C:9C) [17:53:54:833]: Invoking remote custom action. DLL: C:\Users\ADM-JI~1.COR\AppData\Local\Temp\MSI3F3D.tmp, Entrypoint: VSFindInstances2
CustomAction VSFindInstances2 returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
MSI (c) (2C:9C) [17:53:58:307]: Closing MSIHANDLE (4) of type 790542 for thread 21040
Action ended 17:53:58: VSFindInstances2. Return value 3.
MSI (c) (2C:30) [17:53:58:309]: Doing action: FatalError
Action 17:53:58: FatalError. 
Action start 17:53:58: FatalError.
Action 17:53:58: FatalError. Dialog created

我克隆了你的存储库和 运行 MSI 几次,但我无法重现你的问题。 CA 每次安装时都会触发。请注意,我确实看到了我希望看到的 SfxCA 行。我在你的身上没有看到这个。

您是否在多台机器上测试过这个,尤其是干净的 VM 快照?我怀疑您的环境问题导致 DTF 崩溃并导致您的 CA 无法启动。如果您能找到它的根本原因并且看起来 DTF 可以改进,我会创建 WiX 问题。

=== 详细日志记录开始:4/8/2022 8:49:31 构建类型:SHIP UNICODE 5.00.10011.00 调用进程:C:\WINDOWS\system32\msiexec.exe === MSI (c) (08:E0) [08:49:31:374]:执行操作:VSFindInstances2 MSI (c) (08:E0) [08:49:31:374]: 注意: 1: 2205 2: 3: ActionText 操作 8:49:31:VSFindInstances2。 动作开始 8:49:31:VSFindInstances2。 MSI (c) (08:08) [08:49:31:380]:调用远程自定义操作。 DLL:C:\Users\cxp5196\AppData\Local\Temp\MSI920B.tmp,入口点:VSFindInstances2 SFXCA:将自定义操作提取到临时目录:C:\Users\cxp5196\AppData\Local\Temp\MSI920B.tmp-
SFXCA:绑定到 CLR 版本 v4.0.30319 调用自定义操作 VSLocator!VSLocator.CustomActions.VSFindInstances2 VSFindInstances2 输入 InstanceId:97a9f9ed(完整) 安装版本:17.1.32210.238 (4785081009963246) 安装路径:C:\Program Files\Microsoft Visual Studio22\Enterprise 操作结束 8:49:31:VSFindInstances2。 Return 值 1.

=== 详细日志记录开始:4/8/2022 8:49:46 构建类型:SHIP UNICODE 5.00.10011.00 调用过程:C:\WINDOWS\system32\msiexec.exe ===

操作8:49:47:VSFindInstances2。 动作开始 8:49:47:VSFindInstances2。 MSI (c) (90:B8) [08:49:47:088]:调用远程自定义操作。 DLL:C:\Users\cxp5196\AppData\Local\Temp\MSICF62.tmp,入口点:VSFindInstances2 SFXCA:将自定义操作提取到临时目录:C:\Users\cxp5196\AppData\Local\Temp\MSICF62.tmp-
SFXCA:绑定到 CLR 版本 v4.0.30319 调用自定义操作 VSLocator!VSLocator.CustomActions.VSFindInstances2 VSFindInstances2 输入 InstanceId:97a9f9ed(完整) 安装版本:17.1.32210.238 (4785081009963246) 安装路径:C:\Program Files\Microsoft Visual Studio22\Enterprise 操作结束 8:49:47:VSFindInstances2。 Return 值 1.