ServiceBase.跑步,为什么可以';t我抓住了它';或以其他方式对其作出反应

本文关键字:方式 其他 为什么 跑步 ServiceBase | 更新日期: 2023-09-27 18:07:39

我从入口点静态主方法调用以下内容:

    try { ServiceBase.Run(new MonitorSer()); }
    catch (Exception ex) { Console.WriteLine(ex.Message + Process.GetCurrentProcess().MainModule.FileName); }

MonitorSer是的一个实例

class MonitorSer : ServiceBase {

entry-main方法是我类的一个成员:

[RunInstaller(true)]
public class WindowsServiceInstaller : Installer {

我在捕捉异常进行调试时取得了很好的结果,但有时它们似乎会找到自己的方法绕过我的陷阱,就像在本例中一样。

当我真正想要的是找到这个进程的名称并用-I开关再次调用它时,我会收到一个windows框的提示,告诉我我需要使用installutil进行安装,我已经连接好了这个开关,使它能够安装intself(这要归功于这里那些贡献/回收该代码的人(。

更令人沮丧的是,如果我在调用ServiceBase时设置断点。Run,它将无声地失败,我只剩下闪烁的控制台。

更新

    static void Install(bool undo, string[] args)
    {
        try
        {
            Console.WriteLine(undo ? "uninstalling" : "installing");
            using (AssemblyInstaller inst = new AssemblyInstaller(typeof(MonitorSer).Assembly, args))
            {
                IDictionary state = new Hashtable();
                inst.UseNewContext = true;
                try
                {
                    if (undo) inst.Uninstall(state);
                    else
                    {
                        inst.Install(state);
                        inst.Commit(state);
                    }
                }
                catch
                {
                    try
                    {
                        inst.Rollback(state);
                    }
                    catch { }
                    throw;
                }
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine(ex.Message);
        }
    }

我把入口点聚集在这里,这样我就可以调用上面的函数,我会尝试把它移到另一个类,并在那里设置入口点,但我知道我可以通过用适当的参数调用它自己来安装这个入口点(你Dmitry拒绝了(——只有BaseService类才能这样做——如果我错了,就纠正我。

ServiceBase.跑步,为什么可以';t我抓住了它';或以其他方式对其作出反应

[RunInstaller(true)]
public class WindowsServiceInstaller : Installer

不是你的切入点。当您使用InstallUtil.exe安装服务时,会调用一次。入口点可以在项目属性中指定,通常默认为Program.Main。您不应该从安装程序类启动服务。

如果您订阅了以下事件,CLR将通知您未处理的异常:

static void Main() {
    ...
    AppDomain.CurrentDomain.UnhandledException 
                                      += CurrentDomain_UnhandledException;
    ...
}
private static void CurrentDomain_UnhandledException(
                                                 Object sender, 
                                                 UnhandledExceptionEventArgs e) {
    if (e != null && e.ExceptionObject != null) {
        // log exception:
    }
}

此事件提供未捕获异常的通知。它允许用于在系统之前记录有关异常的信息的应用程序默认处理程序向用户报告异常并终止应用程序。。。从开始。NET Framework版本4,未引发此事件对于损坏进程状态的异常,例如堆栈溢出或访问冲突,除非事件处理程序安全性至关重要,并且具有HandleProcessCorruptedStateExceptionsAttribute属性。应用

您可能希望在windows服务中记录异常的另一个地方(因为.NET/SCM会吞下启动异常(:

protected override void OnStart(String[] args) {
    try {
    } catch(Exception e) {
        // log exception:
        throw;
    }
}