C# C安装项目自定义操作,将安装目录保存到自定义设置文件

C# C安装项目自定义操作,将安装目录保存到自定义设置文件,c#,windows-installer,setup-project,custom-action,settings.settings,C#,Windows Installer,Setup Project,Custom Action,Settings.settings,我正在尝试使用windows installer作为安装方法来创建应用程序。当安装成功时,我希望获得我在安装程序中配置的主输出所在的路径。在我的例子中,主要输出在文件夹[ApplicationDataInstallroot]\Bin\中 我的类库中还有一个名为App.settings的自定义设置文件,它控制多个设置,例如相对于安装位置的文件位置 因此,当安装成功时,它应该调用App.Settings并将安装文件夹保存到设置文件中 我已经创建了一个Install类并将其放入类库中。但我不确定它是否

我正在尝试使用windows installer作为安装方法来创建应用程序。当安装成功时,我希望获得我在安装程序中配置的主输出所在的路径。在我的例子中,主要输出在文件夹[ApplicationDataInstallroot]\Bin\中

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

因此,当安装成功时,它应该调用App.Settings并将安装文件夹保存到设置文件中

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

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文件,包括类库

我真的不确定从这一点上继续,但因为设置没有保存。我只需在应用程序启动时设置一个消息框,给我设置的值来检查这一点

任何对该项目的更多数据感兴趣的人都可以问。我只是暂时还不会把所有的东西都发出去

编辑:

经过更多的测试,我发现安装程序类没有被调用。我添加了一些东西,当调用该方法但什么也没发生时,会写入文件


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

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


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

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


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

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

添加自定义操作的步骤

在解决方案资源管理器中选择安装程序项目。在…上 在“视图”菜单中,指向“编辑器”,然后单击“自定义操作”。这个 将显示自定义操作编辑器。 在自定义操作编辑器中,选择提交节点。关于行动 菜单中,单击添加自定义操作。 在“在项目中选择项”对话框中,双击 应用程序文件夹。从InstallerActions中选择主输出 项目InstallerActions的主输出显示在 在自定义操作编辑器中提交节点。 在“属性”窗口中,确保InstallerClass属性 设置为True这是默认设置。 在自定义操作编辑器中,选择安装节点并添加 从InstallerActions到该节点的主输出与您对 提交节点。
您可以将自定义操作类.dll添加到安装项目中。您必须将InstallerActions.dll添加到安装和提交操作中

添加自定义操作的步骤

在解决方案资源管理器中选择安装程序项目。在…上 在“视图”菜单中,指向“编辑器”,然后单击“自定义操作”。这个 将显示自定义操作编辑器。 在自定义操作编辑器中,选择提交节点。关于行动 菜单中,单击添加自定义操作。 在“在项目中选择项”对话框中,双击 应用程序文件夹。选择主输出f rom安装操作 项目InstallerActions的主输出显示在 在自定义操作编辑器中提交节点。 在“属性”窗口中,确保InstallerClass属性 设置为True这是默认设置。 在自定义操作编辑器中,选择安装节点并添加 从InstallerActions到该节点的主输出与您对 提交节点。
我也有同样的问题。在经历了很多挫折之后,我发现msi安装程序只在更新期间使用应用程序的安装程序类,即RemovePreviousVersions=true。因此,如果您卸载并重新安装该应用程序,它将正常工作

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

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

不幸的是,安装程序类仍然需要两次更新才能正确地渗透到安装程序中。大概,可以通过添加更低的序列号来删除msi文件中的现有产品来解决这个问题,但我现在已经不再处理这个问题了。

我也遇到了同样的问题。在经历了很多挫折之后,我发现msi安装程序只在更新期间使用应用程序的安装程序类,即RemovePreviousVersions=true。因此,如果您卸载并重新安装该应用程序,它将正常工作

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

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

不幸的是,安装程序类仍然需要两次更新才能正确地渗透到安装程序中。大概可以通过添加更低的序列号来删除msi文件中的现有产品来解决这个问题,但我现在已经不想再处理这个问题了。

所以如果我做对了,在提交后,找到设置文件并直接编辑它?我偶然发现了这个:。VS2015也是如此吗?如果是这样的话,那么我就知道我的代码为什么不起作用了。根据你的问题,这似乎与你无关,因为它涉及到调试和缺少base.Install。好吧,我已经用另一种方式做到了。我现在不再在安装过程中保存installdir,而是在第一次启动时从system.Reflection获取AssemblyPath并直接保存。不过还是要谢谢你的帮助。所以如果我做对了,在提交之后,找到设置文件并直接编辑它?我偶然发现了这个:。VS2015也是如此吗?如果是这样的话,那么我就知道我的代码为什么不起作用了。根据你的问题,这似乎与你无关,因为它涉及到调试和缺少base.Install。好吧,我已经用另一种方式做到了。我现在不再在安装过程中保存installdir,而是在第一次启动时从system.Reflection获取AssemblyPath并直接保存。不过还是要感谢你的帮助。你应该在回答中提供更多细节,因为外部链接可能会随着时间的推移而中断。你应该在回答中提供更多细节,因为外部链接可能会随着时间的推移而中断。