添加WiX自定义操作将MSI日志文件复制到LOCALAPPDATA文件夹

本文关键字:复制 文件 LOCALAPPDATA 文件夹 日志 MSI WiX 自定义 操作 添加 | 更新日期: 2023-09-27 17:53:34

如何编写一个WiX自定义操作

  1. 总是在安装结束时调用,至少在出现安装错误的情况下
  2. 将当前MSI日志文件从当前本地复制到用户的APPDATA文件夹

我有这个管理的自定义操作代码。不确定如何在我的Wix脚本中编写它的调用。应该在InstallFinalize之后安排自定义操作吗?可以安排OnExit="错误"吗?

    [CustomAction]
    public static void CopyLogFile(Session session)
    {
        const string company = "MyCompany";
        const string product = "MyProduct";
        try
        {
            session.Log("CustomAction.CopyLogFile entry");
            var msiLogFilePath = session.CustomActionData["LOGFILEPATH"];
            if (msiLogFilePath != null)
            {
                session.Log("CustomAction.CopyLogFile MSI log filename: {0}", msiLogFilePath);
                var localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                var destDirPath = Path.Combine(localAppDataPath, company, product);
                var destDir = Directory.CreateDirectory(destDirPath);
                session.Log("CustomAction.CopyLogFile Destination directory: {0}", destDir.FullName);
                var destFilePath = Path.Combine(destDir.FullName, Path.GetFileName(msiLogFilePath));
                File.Copy(msiLogFilePath, destFilePath, true);
                session.Log("CustomAction.CopyLogFile Log file copied to: {0}", destFilePath);
            }
            else
            {
                session.Log("CustomAction.CopyLogFile File path not found");
            }
        }
        catch (Exception exception)
        {
            session.Log("CustomAction.CopyLogFile exception {0}", exception);
        }
        finally
        {
            if (session != null)
            {
                session.Log("CustomAction.CopyLogFile exit");
                session.Close();
            }
        }
    }

添加WiX自定义操作将MSI日志文件复制到LOCALAPPDATA文件夹

是的,您可以在InstallFinalize之后安排它(我也是这样做的,但如果不是完全删除包,我每次都会复制它):

<InstallExecuteSequence>
    <Custom Action="CopyLogfile" After="InstallFinalize">NOT (REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE)</Custom>
</InstallExecuteSequence>

如果有的话,请记住将其添加到UI序列中。我将其作为事件添加到SetupCompleteSuccess -和SetupCompleteError -对话框中的PushButton(也许您只需要将其添加到后者?),如下所示:

<Dialog Id="SetupCompleteSuccess" X="50" Y="50" Width="374" Height="266" Title="[ProductName]" NoMinimize="yes">
     <Control Id="OK" Type="PushButton" X="230" Y="243" Width="66" Height="17" Text="&amp;Finish" TabSkip="no" Default="yes" Cancel="yes">
           <Publish Event="EndDialog" Value="Exit">1</Publish>
           <!-- ### Invoking copying the logfile if the Finish-button is pressed -->
           <Publish Event="DoAction" Value="CopyLogfile">MsiLogFileLocation AND NOT (REMOVE="ALL" AND NOT UPGRADINGPRODUCTCODE)</Publish>
    </Control>
 <!-- ... rest of the dialog ... -->
</Dialog>

关于显示它只在一个错误的情况下:也许检查ProductState -属性?我在网上搜索了一下,但没有找到任何有用的东西。

编辑:也许只有在发生错误的情况下才能执行它的正确方法是使用自定义动作标志,仅在回滚期间执行它。在WiX中,它将是CustomAction标记的Execute="rollback" -属性。

如果可以的话,不要在InstallFinalize之后乱搞自定义操作。当通过SCCM、Unicenter等工具部署时,它们通常会被完全跳过。

在安装结束时使用带有打开日志文件按钮的自定义对话框可以正常工作。