【问题标题】:Passing parameters to Windows Service during installation在安装期间将参数传递给 Windows 服务
【发布时间】:2015-07-05 15:03:03
【问题描述】:

我正在创建一个 Windows 服务,它假设在特定表中查找数据,然后根据状态处理记录。

我想在使用 installutill 作为参数安装服务时传递数据库凭据并将它们保存在注册表中。我曾尝试使用下面的代码这样做,但在“OnBeforeInstall”事件中不断出现错误。

我认为要么是我错误地传递了参数,要么是我在错误的事件中编写代码。需要你的帮助来弄清楚我做错了什么。

protected override void OnBeforeInstall(IDictionary savedState)
{
    base.OnBeforeInstall(savedState);
    _eventLog.WriteEntry("OnBeforeInstall Started");
    try
    {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\RyteRMS");
        if (key != null)
        {
            _eventLog.WriteEntry("Write data to registry key");
            key.SetValue("DBTYPE", this.Context.Parameters["dbtype"].ToString()); // This throws error, I am assuming as the above event entry is visible.
            key.SetValue("DATASOURCE", this.Context.Parameters["datasource"].ToString());
            key.SetValue("USERID", this.Context.Parameters["userid"].ToString());
            key.SetValue("PASSWORD", this.Context.Parameters["password"].ToString());
            key.SetValue("DBNAME", this.Context.Parameters["dbname"].ToString());
            key.Close();
        }
    }
    catch (Exception ex)
    {
        _eventLog.WriteEntry(ex.Message);
    }
    _eventLog.WriteEntry("OnBeforeInstall Finished");
}

我在命令提示符下写这个: installutil RMSBGService.exe /dbtype=sqlserver /datasource=hitin-lt /dbname=rms /userid=admin /password=passw0rd

错误:“对象引用未设置为对象的实例。”

附:我不知道如何调试 Win 服务,所以我使用事件日志记录每一件事。

【问题讨论】:

    标签: c# asp.net windows-services registry installutil


    【解决方案1】:

    设法自己做,这是我们应该做的。

    protected override void OnBeforeInstall(IDictionary savedState)
    {
        _eventLog.WriteEntry("OnBeforeInstall Started");
        try
        {
            RegistryKey key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(@"SOFTWARE\RMS");
            if (key != null)
            {
                _eventLog.WriteEntry("Write data to registry key");
    
                Process _prc = new Process();
                _prc.StartInfo.FileName = "cmd.exe";
                _prc.StartInfo.UseShellExecute = false;
                _prc.StartInfo.RedirectStandardOutput = true;
                _prc.StartInfo.RedirectStandardInput = true;
                _prc.Start();
    
                ConsoleColor _color = Console.ForegroundColor;
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.WriteLine("\n\n");
                Console.WriteLine("PLEASE ENTER FOLLOWING DETAILS TO COMPLETE SETUP");
                Console.WriteLine("NOTE: if you enter wrong information, you will need to reinstall the application.");
                Console.WriteLine("\n\n");
                Console.WriteLine("Enter DBTYPE (SQLSERVER or ORACLE):");
                key.SetValue("DBTYPE", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter DATASOURCE (SERVER NAME):");
                key.SetValue("DATASOURCE", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter DATABASE USER ID:");
                key.SetValue("USERID", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter PASSWORD:");
                key.SetValue("PASSWORD", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                Console.WriteLine("Enter DATABASE NAME:");
                key.SetValue("DBNAME", StringCipher.Encrypt(Console.ReadLine(), "@xx"));
                key.Close();
                Console.ForegroundColor = _color;
                _prc.Close();
            }
        }
        catch (Exception ex)
        {
            _eventLog.WriteEntry(ex.Message);
        }
        _eventLog.WriteEntry("OnBeforeInstall Finished");
        base.OnBeforeInstall(savedState);
    }
    

    StringCipher 是我用来加密/解密文本的自定义函数。稍后开始,我从注册表中读取这些存储的值,并将它们解密以将其传递到数据库连接代码并做必要的事情。

    希望这会对某人有所帮助。

    注意

    您必须使用“InstallUtil”安装此服务,如果您选择使用安装项目安装它,此安装将卡住并打开一个 cmd 窗口。

    【讨论】:

    • 感谢您的回答,我将补充一点,我正在使用 WPF 应用程序中的ManagedInstallerClass.InstallHelper() 来安装服务,然后从服务的 c'tor 读取注册表值。是的,我知道它公开了 API,不应该从代码中使用 :-) 它是启用使用 GUI 安装服务的临时解决方案。
    猜你喜欢
    • 1970-01-01
    • 2021-02-21
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2017-08-06
    • 2013-05-22
    相关资源
    最近更新 更多