使用带参数的自定义操作时,MSI安装程序无法找到InstallState

时间:2011-02-15 19:41:17

标签: c# .net installer custom-action

首先,是的,我知道VS Setup Projects是邪恶的。这就是我必须要做的事情。我也看到了几个相关的问题,但是它们要么没有答案,要么与我的情况不符,足以让工作的答案(或者他们对VS Setup Projects和WiX的奇迹有所了解)。

我的应用程序有一个安装项目。它可以很好地复制文件,但我需要在复制文件后执行两个自定义操作。我创建了一个安装程序类,并将其设置为安装项目中的自定义操作,并且它的框架(没有工作,只显示一个对话框,所以我可以附加调试器并环顾四周)工作得很好。然后,我发现我需要将参数从MSI传递到我的自定义操作,以便我可以通过安装程序类的Context属性访问它们。

这是安装程序类的当前代码(某些名称已被更改以保护无辜者)。它基本上什么都不做,只是在正确的时间显示一个对话框(在复制文件之后但在提交安装之前):

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

        protected override void OnAfterInstall(IDictionary savedState)
        {
            try
            {
                base.OnAfterInstall(savedState);
                if (MessageBox.Show(
                    "Custom Action OnAfterInstall successfully integrated. You can attach a debugger if desired. Do you wish to perform the custom actions?",
                    "DEBUG", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;

                SetEditablePermissionOnFolder(savedState);
                SetApplicationSettingsFromWizard(savedState);
            }
            catch (Exception ex)
            {
                Context.LogMessage(ex.ToString());
                throw;
            }
        }

        private void SetApplicationSettingsFromWizard(IDictionary savedState)
        { 
            //TODO: Implement
        }

        private void SetEditablePermissionOnViewerFolder(IDictionary savedState)
        {
            //TODO: Implement
        }
    }
}

计划是让自定义操作正常工作,然后取出对话框就行了。

以下是CustomActionData的字符串,用于安装项目的自定义操作的安装操作:

/phonenumber=[phonenumber] /thirdpartyinstallpath1="[thirdpartyinstallpath1]\" /thirdpartyinstallpath2="[thirdpartyinstallpath2]\" /thirdpartyinstallpath3="[thirdpartyinstallpath3]\"

如果我不使用这个参数字符串,那很好,但我没有参数。如果我确实指定了此字符串,则安装程序会在我自己的对话框出现之前失败,并出现两个错误:"Exception occurred while initializing the installation: Could not load file or assembly 'file:///C:\Windows\SysWOW64\Files' or one of its dependencies. The system cannot find the file specified""Error 1001. Could not find file C:\Program Files (x86)\MyCompany\MyApp\MyApp.Install.CustomSetup.InstallState"

我做错了什么?我做错了吗?有没有一个解决方案不需要我使用一些不同的框架重新创建安装程序?

编辑:我发现删除除电话号码参数以外的所有内容,并将[PHONENUMBER]放在引号中,可以传递该参数。但是,我无法传递任何目录路径;我尝试了[INSTALLDIR]几个博客和演练如何做到这一点,没有骰子。

6 个答案:

答案 0 :(得分:9)

我有类似的问题并通过以下方式解决:

在自定义操作的属性上将InstallerClass设置为false。

答案 1 :(得分:6)

我发现问题出在参数字符串的格式中。因为各种参数虽然是文件路径,但是包含文件名而不是以反斜杠结尾,所以我不需要使用尾部反斜杠来结束这些值字符串。因为无论如何,结尾引号被视为字符串的一部分,这使得解析器使用下一个开头引号作为前一个值的结尾,破坏了整个参数字符串。因此,无法正确编写InstallState,并且在自定义安装逻辑尝试使用它时失败。

答案 2 :(得分:2)

如果有任何人在从VS2008升级到VS2010后出现此错误 ,请查看此主题: http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/829d5c90-9a0d-4258-9d4d-1341cc50f95b/

这解决了我的问题:

  

在安装项目属性上将“BackwardCompatibleIDGeneration”更改为true。

答案 3 :(得分:1)

我要确定的一件事是我的路径被正确地逃脱了;要么用

@"My Documents\Blah"

"My\ Documents\\Blah"

答案 4 :(得分:0)

在我的情况下,这是因为我错误地将自定义操作添加到回滚节点而不是安装节点。简单的错误。

答案 5 :(得分:0)

问题是终止引号前面的一个反斜杠将被解释为属于String的引用,并且不会终止字符串。 在CustomactionActionData字符串

/thirdpartyinstallpath1="[thirdpartyinstallpath1]\" /thirdpartyinstallpath2="[thirdpartyinstallpath2]\"

用户输入的安装程序替换[thirdpartyinstallpath1][thirdpartyinstallpath2],然后尝试解释CustomactionActionData字符串。 如果“thirdpartyinstallpath1”的用户输入为“C:\ Test \”,则上述CustomactionActionData字符串可能正常,但如果用户输入“C:\ Test”,则安装失败并显示错误

  

"初始化安装时发生异常:无法   加载文件或程序集' file:/// C:\ Windows \ SysWOW64 \ Files ...'或者一个   它的依赖..."

使用像

这样的CustomactionActionData字符串

/thirdpartyinstallpath1="[thirdpartyinstallpath1]" /thirdpartyinstallpath2="[thirdpartyinstallpath2]"

如果用户输入为“C:\ Test \”,安装程序将失败。如果用户输入为“C:\ Test”,则可以。但你永远不知道用户会做什么。

我的解决方法是在终止字符串之前的空白处:

/thirdpartyinstallpath1="[thirdpartyinstallpath1] " /thirdpartyinstallpath2="[thirdpartyinstallpath2] "

因此用户输入不会带走终止字符串。 在代码中,您可以通过Trim

从用户输入中删除所有前导和尾随空白字符