我在安装.Net Windows服务期间无法可靠地创建/删除事件源.
这是我的ProjectInstaller类的代码:
// Create Process Installer ServiceProcessInstaller spi = new ServiceProcessInstaller(); spi.Account = ServiceAccount.LocalSystem; // Create Service ServiceInstaller si = new ServiceInstaller(); si.ServiceName = Facade.GetServiceName(); si.Description = "Processes ..."; si.DisplayName = "Auto Checkout"; si.StartType = ServiceStartMode.Automatic; // Remove Event Source if already there if (EventLog.SourceExists("AutoCheckout")) EventLog.DeleteEventSource("AutoCheckout"); // Create Event Source and Event Log EventLogInstaller log = new EventLogInstaller(); log.Source = "AutoCheckout"; log.Log = "AutoCheckoutLog"; Installers.AddRange(new Installer[] { spi, si, log });
引用的facade方法只返回日志,服务等名称的字符串.
此代码大部分时间都有效,但最近安装后我开始在应用程序日志中显示日志条目而不是自定义日志.并且日志中也存在以下错误:
无法找到源(AutoCheckout)中事件ID(0)的说明.本地计算机可能没有必要的注册表信息或消息DLL文件来显示来自远程计算机的消息.您可以使用/ AUXSOURCE =标志来检索此描述; 请参阅帮助和支持以获取详细信
由于某种原因,它在卸载期间没有正确删除源,或者在安装期间没有创建它.
任何有关最佳实践的帮助表示赞赏.
谢谢!
另外,这里是我如何编写日志异常的示例:
// Write to Log EventLog.WriteEntry(Facade.GetEventLogSource(), errorDetails, EventLogEntryType.Error, 99);
关于stephbu的答案:推荐的路径是安装程序脚本和installutil,或Windows安装例程.
我正在使用安装项目,它执行服务的安装并设置日志.无论我使用的是installutil.exe还是windows安装项目,我相信它们都会调用上面显示的相同的ProjectInstaller类.
我看到如果在重新启动之前没有真正删除日志,我的测试机器的状态可能会导致错误.我将进行更多实验,看看是否能解决问题.
编辑: 我对在安装服务期间注册源和日志名称的确定方法感兴趣.因此,如果先前已安装该服务,它将删除源,或在后续安装期间重用该源.
我还没有机会学习WiX来尝试这条路线.
该ServiceInstaller
级自动创建一个EventLogInstaller
并把它自己的安装程序集合中.
试试这段代码:
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller(); serviceProcessInstaller.Password = null; serviceProcessInstaller.Username = null; serviceProcessInstaller.Account = ServiceAccount.LocalSystem; // serviceInstaller ServiceInstaller serviceInstaller = new ServiceInstaller(); serviceInstaller.ServiceName = "MyService"; serviceInstaller.DisplayName = "My Service"; serviceInstaller.StartType = ServiceStartMode.Automatic; serviceInstaller.Description = "My Service Description"; // kill the default event log installer serviceInstaller.Installers.Clear(); // Create Event Source and Event Log EventLogInstaller logInstaller = new EventLogInstaller(); logInstaller.Source = "MyService"; // use same as ServiceName logInstaller.Log = "MyLog"; // Add all installers this.Installers.AddRange(new Installer[] { serviceProcessInstaller, serviceInstaller, logInstaller });
这里有几件事
动态创建事件日志和源代码非常不受欢迎.主要是因为执行操作所需的权利 - 你真的不想用这种力量祝福你的应用程序.
此外,如果删除事件日志或源,则只有在服务器重新启动时才会真正删除该条目,因此如果删除并重新创建条目而不弹出框,则可以进入奇怪的状态.由于元数据存储在注册表中的方式,还有一些关于命名冲突的不成文规则.
建议的路径是安装程序脚本和installutil,或Windows安装例程.
最好的建议是不要在Visual Studio中使用安装项目.它有非常严重的局限性.我用WiX做了很好的结果