相关疑难解决方法(0)

我是作为一种服务运行的

我目前正在为可以在控制台中运行的服务编写一些引导代码.它本质上归结为调用OnStart()方法而不是使用ServiceBase来启动和停止服务(因为如果它没有作为服务安装并且使调试成为一场噩梦,它就不会运行应用程序).

现在我使用Debugger.IsAttached来确定我是否应该使用ServiceBase.Run或[service] .OnStart,但我知道这不是最好的主意,因为有些时候最终用户想要在控制台中运行服务(看看输出等实时).

关于如何确定Windows服务控制器是否启动"我",或者用户是否在控制台中启动"我"的任何想法?Apparantly Environment.IsUserInteractive不是答案.我想过使用命令行args,但这看起来很"脏".

我总是可以看到围绕ServiceBase.Run的try-catch语句,但这看起来很脏.编辑:尝试捕获不起作用.

我有一个解决方案:把它放在这里给所有其他感兴趣的堆叠器:

    public void Run()
    {
        if (Debugger.IsAttached || Environment.GetCommandLineArgs().Contains<string>("-console"))
        {
            RunAllServices();
        }
        else
        {
            try
            {
                string temp = Console.Title;
                ServiceBase.Run((ServiceBase[])ComponentsToRun);
            }
            catch
            {
                RunAllServices();
            }
        }
    } // void Run

    private void RunAllServices()
    {
        foreach (ConsoleService component in ComponentsToRun)
        {
            component.Start();
        }
        WaitForCTRLC();
        foreach (ConsoleService component in ComponentsToRun)
        {
            component.Stop();
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑:在StackOverflow上有另一个问题,那个人有环境问题.CurrentDirectory是"C:\ Windows\System32"看起来可能是答案.我今天要考试.

.net c# windows-services

44
推荐指数
6
解决办法
3万
查看次数

如何检测我是否在控制台中运行

是否有一种简单的方法可以让代码库自动检测是否从控制台应用程序或Windows应用程序调用它?我希望我的库不报告Windows事件日志,如果它是从控制台窗口调用,而是报告给控制台窗口.但是,如果它不在控制台窗口中运行,则应报告给Windows事件日志.

我考虑过要求我的日志记录组件传递日志目标,但如果它本身可以自动处理这两个目标,它会很整洁.我还没有需要像log4net这样广泛的东西,事实上,如果有必要提供支持来记录数据库/文件和其他未知的日志记录目标,那么我可能会推荐这样的解决方案.现在,只是让我的组件自动检测环境并根据环境登录到控制台或事件日志就足够了.

.net c# vb.net logging

16
推荐指数
2
解决办法
7867
查看次数

从库中捕获主线程SynchronizationContext或Dispatcher

我有一个C#库,希望能够发送/发布工作到"主"ui线程(如果存在).该库可用于:

  • 一个winforms应用程序
  • 本机应用程序(带UI)
  • 控制台应用程序(没有UI)

在库中我想在初始化期间捕获一些东西(A SynchronizationContext,Dispatcher,Task Scheduler或其他东西),这将允许我(稍后)将发送/后期工作发送到主线程(如果主线程有这种能力 - 即它有一个消息泵).例如,当且仅当主应用程序能够访问主线程时,库才会在主线程上放置一些Winforms UI.

我试过的事情:

  1. 一个SynchronizationContext:捕获它适用于Winforms应用程序(WindowsFormsSynchronizationContext将作为当前 SynchronizationContext 安装.这也适用于控制台应用程序 - 因为我可以检测到当前SynchronizationContext为空(因此,知道我不知道)没有能力发送/发布工作到主线程.这里的问题是本机UI应用程序:它有能力(即它有一个消息泵),但当前同步上下文为空,因此我可以'将它与Console应用程序案例区分开来.如果我可以区分,那么我可以在主线程上安装一个WindowsFormsSynchronizationContext,我很高兴.
  2. 一个调度员:捕捉这种使用当前创建一个新的SynchronizationContext.因此,在所有情况下,我都会找回Dispatcher.但是,对于Console应用程序,Dispatcher.Invoke从后台线程使用将挂起(如预期的那样).我可以使用Dispatcher.FromThread(如果不存在,则不会为该线程创建Dispatcher).但是本机UI应用程序将使用此方法返回null Dispatcher,因此我再次陷入困境,无法区分UI应用程序和控制台应用程序.
  3. 的TaskScheduler:我可以用FromCurrentSynchronizationContext.这与SynchronizationContext具有相同的问题.即在调用FromCurrentSyncronizationContext之前,我必须检查当前的SynchronizationContext是否为null(这将是Console应用程序和本机ui应用程序的情况).所以,我再次无法将本机ui应用程序与控制台应用程序区分开来.

当然,我可以让我的库的用户在调用我的Initialize方法时指定它是否是UI应用程序,但我希望尽可能避免对库的用户造成这种复杂化.

c# multithreading synchronization winforms

9
推荐指数
1
解决办法
4114
查看次数