【问题标题】:C# Setup Project Custom Action to save the installation directory to custom setting fileC# Setup Project Custom Action 将安装目录保存到自定义设置文件
【发布时间】:2016-07-13 16:24:21
【问题描述】:

我正在尝试使用 Windows 安装程序作为安装方法制作应用程序。安装成功后,我想获取我在安装程序中配置的主要输出所在的路径。就我而言,主要输出位于文件夹 [ApplicationData(Installroot)]\Bin\

我的类库中还有一个名为 App.Settings 的自定义设置文件,它控制多个设置,例如相对于安装位置的文件位置。

所以想法是,当安装成功时,它应该调用 App.Settings 并将安装文件夹保存到设置文件中。

我已经创建了一个安装类并将其放入类库中。我不确定它是否应该在那个项目中。 这是安装类的代码:

using System.Collections;
using System.ComponentModel;

namespace WaspbaneModels
{
    [RunInstaller(true)]
    public partial class Installer : System.Configuration.Install.Installer
    {
        public Installer()
        {
            InitializeComponent();
        }

        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);
        }

        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);

            SettingsControl.BaseURL = Context.Parameters["assemblypath"];
            SettingsControl.Save();
        }

        public override void Rollback(IDictionary savedState)
        {
            base.Rollback(savedState);
        }

        public override void Uninstall(IDictionary savedState)
        {
            base.Uninstall(savedState);
        }
    }
}

在这段代码中,SettingsControl 是一个简单地使用一些属性来处理设置的类。我使用了这个类,以便我的 Windows 窗体项目也可以访问这些设置。

在“自定义操作”选项卡中,我还将主输出添加到所有内容。我也不确定这是否正确,因为我认为主输出包含所有 .dll 文件,包括类库。

我不确定从哪里继续,因为设置没有保存。我只是通过在应用程序启动时放置一个消息框来检查这一点,给我设置的值。

任何对项目的更多数据感兴趣的人都可以询问。我只是暂时不会发布所有内容。

编辑:

经过更多测试后,我设法发现没有调用 Installer 类。我添加了一些内容,当该方法被调用但没有发生任何事情时,它会写入文件。

因此我现在的问题是:如何正确地将自定义操作添加到安装项目?

【问题讨论】:

    标签: c# windows-installer setup-project custom-action settings.settings


    【解决方案1】:

    您可以将自定义操作类 (.dll) 添加到安装项目。您必须将 InstallerActions.dll 添加到安装和提交操作中。

    添加自定义操作

    1. 在解决方案资源管理器中选择 Setup Installer 项目。在 查看菜单,指向编辑器,然后单击自定义操作。这 显示自定义操作编辑器。
    2. 在自定义操作编辑器中,选择 Commit 节点。关于行动 菜单,点击添加自定义操作。
    3. 在“选择项目中的项目”对话框中,双击 应用程序文件夹。从 InstallerActions 中选择主要输出 项目。 InstallerActions 的主要输出出现在 自定义操作编辑器中的提交节点。
    4. 在“属性”窗口中,确保 InstallerClass 属性 设置为 True(这是默认设置)。
    5. 在自定义操作编辑器中,选择 Install 节点并添加 从 InstallerActions 到此节点的主要输出,就像您为 提交节点。

    【讨论】:

    • 您应该在回答中提供更多详细信息,因为外部链接可能会随着时间的推移而中断。
    【解决方案2】:

    设置范例不适用于安装程序类,因为您不在运行的应用程序上下文中。您正在通过使用系统帐户运行的 msiexec.exe 进程的反射被调用,而没有任何工作目录上下文。人们通常直接在设置文件上使用 Xml 处理来避免这种行为。您需要命名设置文件的完整路径,因为您再次作为 msiexec.exe 进程的回调运行。

    自定义操作不需要是 Commit 自定义操作,因为所有 VS 自定义操作都在安装所有文件后运行。唯一需要 Commit 自定义的操作是当您运行依赖于安装到 WinSxS 上的 GAC 中的文件的代码时,因为它们在 Commit 时间之前无法访问。

    【讨论】:

    • 那么如果我做对了,在commit之后,找到设置文件直接编辑?
    • 我偶然发现了这个:stackoverflow.com/questions/2943438/…。 VS2015 也是这样吗?如果是这样,那么我知道为什么我的代码不起作用了。
    • 这似乎与您的问题无关,因为它涉及调试和缺少 base.Install()。
    • 好吧,我已经设法以另一种方式做到了。我现在没有在安装过程中保存 installdir,而是在第一次启动时从 system.Reflection 获取 AssemblyPath 并直接保存。不过还是谢谢你的帮助。
    【解决方案3】:

    我遇到了同样的问题。在经历了很多挫折之后,我发现 msi 安装程序仅在 RemovePreviousVersions = true 更新期间使用第一次安装时的应用程序安装程序类。因此,如果您卸载该应用程序并重新安装,它就可以工作。

    作为一种解决方法,我发现在安装过程的早期卸载以前的版本可以解决此问题。 RemoveExistingProducts 的序列号必须在 msi 安装程序 documented in SO here 中移动到较低的值。这可以使用 orca 手动完成,也可以通过运行找到 here 作为 VS PostBuildEvent 的 vbs 脚本自动完成:

    cscript.exe ..\Msi_Fix_RemoveExistingProducts_Record.vbs yourOutput.msi
    

    不幸的是,安装程序类仍然需要两次更新才能正确渗透到安装程序中。据推测,这可以通过在 msi 文件中向RemoveExistingProducts 添加一个更低的序列号来解决,但我现在已经完成了这个操作。

    【讨论】:

      【解决方案4】:

      我今天也遇到了同样的问题。
      我的问题与我用作类库的项目类型有关。
      我正在选择一个类库类型的新项目。
      我将其更改为类库(.NET Framework)。

      【讨论】:

        猜你喜欢
        • 2015-07-11
        • 1970-01-01
        • 2012-05-14
        • 2011-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-05
        相关资源
        最近更新 更多