OnAfterInstall事件处理程序

时间:2015-05-28 15:39:01

标签: c# visual-studio-2013 windows-services windows-installer setup-project

注意:我在过去的两天里研究了这个问题,我看到了非常相似的问题和答案,但没有一个解决了我的情况,因此我在经过深入研究后提出了这个问题。

我在VS2013中创建了一个Windows服务和安装项目。一切都很好,安装程序工作正常。我遇到了服务无法在部署机器上启动的问题,因为它无法找到所需的.dll文件。在努力的同时,另一个问题开始发生。在安装时我开始收到此错误:错误1001:"此处为servicename"的OnAfterInstall事件处理程序发生异常,参数名称值无效。

我将文件路径从安装程序传递到Context以写入app.Config文件。值得很好[我成功调试了]

我的安装程序类:

[RunInstaller(true)]
    public partial class InstallHelper : Installer
    {
        private readonly ServiceProcessInstaller processInstaller;
        private readonly ServiceInstaller serviceInstaller;

        public InstallHelper()
        {
            processInstaller = new ServiceProcessInstaller();
            serviceInstaller = new ServiceInstaller();

            processInstaller.Account = ServiceAccount.LocalSystem;
            serviceInstaller.StartType = ServiceStartMode.Automatic;
            serviceInstaller.ServiceName = "myServiceName";


            this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall);
        }

        public override void Install(IDictionary statesaver)
        {
            System.Diagnostics.Debugger.Launch();

            base.Install(statesaver);// <-- exception occurs here, statesaver count = 0: I'm not sure if it's supposed to be count = 0 but that seems to be suspicious to me.

        try
        {
            // Grab data from the textbox values
            // This is set to /PathValue=[WATCHPATH]... in CustomActionData property
        string watchPath = null;
        string outputPath = null;
        string connType = null;
        string timeOut = null;
        string serialPort = null;
        string destIP = null;

        string parameters = Context.Parameters["PathValue"];
        char[] c = new char[] { ' ', ',' };
        string[] components = parameters.Split(c, StringSplitOptions.None);

        watchPath = components[0];
        outputPath = components[1];
        connType = components[2];
        timeOut = components[3];
        serialPort = components[4];
        destIP = components[5];

        // Get path to the executable that is being installed 
        string assemblyPath = Context.Parameters["assemblypath"];
        string appConfigPath = assemblyPath + ".config";

        // Write the path to the app.config file
        XmlDocument doc = new XmlDocument();
        doc.Load(appConfigPath);

        XmlNode configuration = null;
        foreach (XmlNode node in doc.ChildNodes)
            if (node.Name == "configuration")
                configuration = node;

        if(configuration != null)
        {
            // Get the appSettings node
            XmlNode settingNode = null;
            foreach(XmlNode node in configuration.ChildNodes)
                if (node.Name == "appSettings")
                    settingNode = node;

            if(settingNode != null)
            {
                // Get the node with the attribute key=FilePath

                XmlNode watchNode = null;
                XmlNode outputNode = null;
                XmlNode connTypeNode = null;
                XmlNode timeOutNode = null;
                XmlNode serialPortNode = null;
                XmlNode destIPNode = null;

                foreach (XmlNode node in settingNode.ChildNodes)
                    if (node.Attributes["key"] != null)
                        if (node.Attributes["key"].Value == "WatchPath")
                            watchNode = node;
                        else if (node.Attributes["key"].Value == "OutPutFile")
                            outputNode = node;
                        else if (node.Attributes["key"].Value == "ConnType")
                            connTypeNode = node;
                        else if (node.Attributes["key"].Value == "TimeOut")
                            timeOutNode = node;
                        else if (node.Attributes["key"].Value == "SerialPort")
                            serialPortNode = node;
                        else if (node.Attributes["key"].Value == "DestIP")
                            destIPNode = node;

                if(watchNode != null && outputNode != null)
                {
                    XmlAttribute xmlwatchAtt = watchNode.Attributes["value"];
                    XmlAttribute xmloutputAtt = outputNode.Attributes["value"];
                    XmlAttribute xmlconntypeAtt = connTypeNode.Attributes["value"];
                    XmlAttribute xmltimeOutAtt = timeOutNode.Attributes["value"];
                    XmlAttribute xmlserialPortAtt = serialPortNode.Attributes["value"];
                    XmlAttribute xmldestIpAtt = destIPNode.Attributes["value"];

                    // Update the appConfig file
                    xmlwatchAtt.Value = watchPath; 
                    xmloutputAtt.Value = outputPath;
                    xmlconntypeAtt.Value = connType;
                    xmltimeOutAtt.Value = timeOut;
                    xmlserialPortAtt.Value = serialPort;
                    xmldestIpAtt.Value = destIP;

                    doc.Save(appConfigPath); // Save the file
                }
            }

        }
    }
    catch(Exception e)
    {
        string err = e.Message;
    }

  }

我也将服务设置为在安装后自动启动:

void ServiceInstaller_AfterInstall(Object sender, InstallEventArgs e)
        {
            using(System.ServiceProcess.ServiceController sc = new System.ServiceProcess.ServiceController(serviceInstaller.ServiceName))
            {
                sc.Start();
            }
        }

我得到的确切错误是: 错误1001:WindowsService.InstallHelper的OnAfterInstall事件处理程序中发生异常。 - &GT;参数名称的值无效。

我确实检查了我从安装程序传递的所有值,并且它们都包含有效数据。

任何帮助或建议都会有所帮助。

谢谢!

0 个答案:

没有答案