69

我最近继承了几个作为 Windows 服务运行的应用程序,并且在为它们提供 gui(可从系统托盘中的上下文菜单访问)时遇到问题。

我们需要 Windows 服务的 gui 的原因是为了能够重新配置 Windows 服务的行为而无需停止/重新启动。

我的代码在调试模式下工作正常,我得到了上下文菜单,一切正常等等。

当我使用命名帐户(即不是本地系统帐户)通过“installutil”安装服务时,服务运行正常,但不会在系统托盘中显示图标(我知道这是正常行为,因为我不具有“与桌面交互”选项)。

但问题是——当我选择“LocalSystemAccount”选项并检查“与桌面交互”选项时,服务需要 AGES 来启动,没有明显的原因,我只是不断收到

无法在本地计算机上启动 ... 服务。

错误 1053:服务没有及时响应启动或控制请求。

顺便说一句,我通过注册表黑客将 Windows 服务超时从默认的 30 秒增加到 2 分钟(请参阅http://support.microsoft.com/kb/824344,在第 3 节中搜索 TimeoutPeriod),但是服务仍然启动超时。

我的第一个问题是 - 为什么“本地系统帐户”登录比使用非 LocalSystemAccount 登录的服务要长得多,从而导致 Windows 服务超时?这两者之间有什么区别会导致启动时出现这种不同的行为?

其次 - 退后一步,我想要实现的只是一个提供配置 gui 的 Windows 服务 - 我很乐意使用非本地系统帐户(使用命名用户/密码)运行,如果我可以让服务与桌面交互(也就是说,在系统托盘中有一个可用的上下文菜单)。这可能吗,如果可以,怎么办?

任何指向上述问题的指针将不胜感激!

4

34 回答 34

76

在与这条消息抗争了几天后,一位朋友告诉我,你必须使用 Release 版本。当我 InstallUtil 调试版本时,它会给出此消息。发布版本开始正常。

于 2011-09-30T14:12:40.300 回答
31

If you continue down the road of trying to make your service interact with the user's desktop directly, you'll lose: even under the best of circumstances (i.e. "before Vista"), this is extremely tricky.

Windows internally manages several window stations, each with their own desktop. The window station assigned to services running under a given account is completely different from the window station of the logged-on interactive user. Cross-window station access has always been frowned upon, as it's a security risk, but whereas previous Windows versions allowed some exceptions, these have been mostly eliminated in Vista and later operating systems.

The most likely reason your service is hanging on startup, is because it's trying to interact with a nonexistent desktop (or assumes Explorer is running inside the system user session, which also isn't the case), or waiting for input from an invisible desktop.

The only reliable fix for these issues is to eliminate all UI code from your service, and move it to a separate executable that runs inside the interactive user session (the executable can be started using the global Startup group, for example).

Communication between your UI code and your service can be implemented using any RPC mechanism: Named Pipes work particularly well for this purpose. If your communications needs are minimal, using application-defined Service Control Manager commands might also do the trick.

It will take some effort to achieve this separation between UI and service code: however, it's the only way to make things work reliably, and will serve you well in the future.

ADDENDUM, April 2010: Since this question remains pretty popular, here's a way to fix another common scenario that causes "service did not respond..." errors, involving .NET services that don't attempt any funny stuff like interacting with the desktop, but do use Authenticode signed assemblies: disable the verification of the Authenticode signature at load time in order to create Publisher evidence, by adding the following elements to your .exe.config file:

<configuration>
    <runtime>
        <generatePublisherEvidence enabled="false"/>
    </runtime>
</configuration>

Publisher evidence is a little-used Code Access Security (CAS) feature: only in the unlikely event that your service actually relies on the PublisherMembershipCondition will disabling it cause issues. In all other cases, it will make the permanent or intermittent startup failures go away, by no longer requiring the runtime to do expensive certificate checks (including revocation list lookups).

于 2008-10-01T16:36:05.550 回答
22

由于运行我的服务的盒子上缺少框架,我遇到了这个问题。盒子有 .NET 4.0,服务是在 .NET 4.5 之上编写的。

我在盒子上安装了以下下载,重新启动,服务启动正常: http ://www.microsoft.com/en-us/download/details.aspx?id=30653

于 2013-09-20T20:39:28.517 回答
14

要调试服务的启动,请将以下内容添加到OnStart()服务方法的顶部:

 while(!System.Diagnostics.Debugger.IsAttached) Thread.Sleep(100);

这将停止服务,直到您使用 Debug -> Attach to Process... 手动附加 Visual Studio 调试器...

注意:通常,如果您需要用户与您的服务进行交互,最好将 GUI 组件拆分为一个单独的 Windows 应用程序,该应用程序在用户登录时运行。然后您可以使用命名管道或其他形式的 IPC在 GUI 应用程序和您的服务之间建立通信。这实际上是在 Windows Vista 中实现此目的的唯一方法。

于 2008-10-01T17:00:36.647 回答
6

在 OnStart 方法中的服务类中不要进行大量操作,操作系统期望运行服务的时间很短,使用线程启动运行您的方法:

protected override void OnStart(string[] args)
{
    Thread t = new Thead(new ThreadStart(MethodName)); // e.g.
    t.Start();
}
于 2011-03-17T11:08:55.357 回答
5

我在这里盲目射击,但我经常发现服务启动的长时间延迟是由网络功能超时直接或间接引起的,通常是在查找帐户 SID 时尝试联系域控制器时 - 这经常通过间接发生GetMachineAccountSid()无论您是否意识到,因为该函数是由 RPC 子系统调用的。

有关如何在这种情况下进行调试的示例,请参阅Mark Russinovich 博客上的进程启动延迟案例。

于 2008-10-01T16:14:38.130 回答
4

If you are using Debug code as below in your service the problem may arise.

#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new EmailService()
};
ServiceBase.Run(ServicesToRun);
#else
//direct call function what you need to run
#endif

To fix this, while you build your windows service remove #if condition because it didn't work as it is.

Please use argument for debug mode instead as below.

if (args != null && args.Length > 0)
{
_isDebug = args[0].ToLower().Contains("debug");
}
于 2014-11-24T10:38:36.190 回答
4

就我而言,问题是缺少.net framework.

我使用的服务

<startup>
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>

但是.net Framework服务器的版本是 4,所以通过将 4.5 更改为 4 解决了问题:

<startup>
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
于 2015-07-11T04:39:34.680 回答
3

我正在编写的服务遇到了类似的问题。它工作得很好,然后有一天我开始收到启动错误的超时。它发生在一个和/或两个版本和调试中,具体取决于发生了什么。我已经从 System.Diagnostics 实例化了一个 EventLogger,但是我看到的任何错误都必须在 Logger 能够写入之前发生......

如果您不知道在哪里查找事件日志,在 VS 中,您可以转到服务器资源管理器下的计算机。除了我的服务之外,我开始查看其他一些事件日志。在 Application - .NETRuntime 下,我发现了与启动错误相关的错误日志。基本上,我的服务的构造函数中有一些异常(一个结果是 EventLog 实例设置中的异常 - 这解释了为什么我在我的 Service EventLog 中看不到任何日志)。在以前的版本中,显然还有其他错误(这导致我进行了导致 EventLog 设置错误的更改)。

长话短说 - 超时的原因可能是由于各种异常/错误,但使用运行时事件日志可能只会帮助您弄清楚发生了什么(特别是在一个构建工作但另一个构建不工作的情况下)。

希望这可以帮助!

于 2013-08-16T18:16:44.440 回答
3

复制发布DLL或从发布模式而不是调试模式获取DLL并将其粘贴到安装文件夹,它应该可以工作

于 2011-02-22T13:56:48.683 回答
2

我想在这里回应 mdb 的评论。不要走这条路。您的服务不应该有 UI...“无用户交互”就像服务的定义功能。

如果您需要配置您的服务,请编写另一个应用程序来编辑服务在启动时读取的相同配置。但是让它成为一个独特的工具——当你想启动服务时,你启动服务。当你想配置它时,你运行配置工具。

现在,如果您需要对服务进行实时监控,那就有点棘手了(当然这也是我希望通过服务实现的)。现在您正在谈论必须使用进程间通信和其他令人头疼的问题。

最糟糕的是,如果您需要用户交互,那么您会在这里真正断开连接,因为服务不与用户交互。

在您的情况下,我会退后一步,问为什么这需要成为一项服务?为什么它需要用户交互

这两个要求是非常不兼容的,这应该引起警报。

于 2008-10-01T18:17:50.453 回答
2

安装服务的调试版本并将调试器附加到服务以查看发生了什么。

于 2008-10-01T16:13:51.907 回答
2

我遇到了这个问题,花了大约一天时间解决。对我来说,问题是我的代码跳过了“主要内容”并有效地运行了几行然后完成。这导致了我的错误。它是一个安装 Windows 服务的 C# 控制台应用程序,一旦它尝试使用 ServiceController (sc.Run() ) 运行它,它就会给我这个错误。

在我修复代码以转到主要内容后,它将运行预期的代码:

ServiceBase.Run(new ServiceHost());

然后它就不再出现了。

正如很多人已经说过的那样,错误可能是任何东西,人们提供的解决方案可能会也可能不会解决它。如果他们没有解决它(比如发布而不是调试,将 generatePublisherEvidence=false 添加到您的配置中等),那么问题很可能出在您自己的代码上。

尝试在不使用 sc.Run() 的情况下运行您的代码(即让 sc.Run() 执行的代码运行)。

于 2014-05-01T22:13:40.530 回答
2

当您的程序集上缺少某些引用并且通常绑定在运行时失败时,通常会出现此问题。

调试Thread.Sleep(1000)放在main(). 并在下一行执行中放置一个断点。

然后启动进程并在启动时将调试器附加到进程。到达断点后按 f5。它将抛出缺少程序集或引用的异常。

希望这将解决此错误。

于 2014-07-28T03:07:25.037 回答
2

我遇到了这个问题,这让我发疯了两天……如果您的问题与我的类似:

我的windows服务中有“用户设置”设置,所以服务可以自行维护,无需停止和启动服务。好吧,问题在于“用户设置”,其中这些设置的配置文件保存在服务-exe文件版本下运行Windows服务的用户的用户配置文件下的文件夹中。

由于某种原因,此文件夹已损坏。我删除了文件夹,服务又像往常一样愉快地开始工作了……</p>

于 2011-03-04T21:45:11.223 回答
2

一旦尝试运行您的 exe 文件。我遇到了同样的问题,但是当我通过双击 exe 文件直接运行它时,我收到一条关于 .Net 框架版本的消息,因为我发布了带有框架的服务项目,但它没有安装在目标机器上。

于 2016-09-04T18:35:22.320 回答
1

将 127.0.0.1 crl.microsoft.com 添加到“Hosts”文件解决了我们的问题。

于 2013-01-15T13:32:11.683 回答
1

在此处输入图像描述

花了我几个小时,应该看到事件查看器get_AppSettings()

应用程序配置的更改导致了问题。

于 2017-08-10T07:47:40.200 回答
1

我的问题是由于 Windows 服务配置中提到的目标框架是

<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
 </startup>

这个.Net版本不支持我尝试安装Windows服务的服务器。

更改 which ,我可以解决问题。

于 2017-10-26T12:57:45.250 回答
1

我有一个类似的问题,我遵循的步骤:

  1. Debugger.Launch()在windows服务构造函数中放一个
  2. 一步一步看它卡在哪里

我的问题不是由于任何错误。我有一个BlockingCollection.GetConsumingEnumerable()导致 Windows 服务等待的方式。

于 2019-04-03T04:32:10.027 回答
0

我也遇到了类似的问题,发现加载程序集有问题。尝试启动服务时,我立即收到此错误。

要快速调试问题,请尝试使用 ProcDump http://technet.microsoft.com/en-us/sysinternals/dd996900通过命令提示符运行服务可执行文件。它应提供有关确切错误的充分提示。

http://bytes.com/topic/net/answers/637227-1053-error-trying-start-my-net-windows-service帮了我不少忙。

于 2012-09-28T07:20:12.260 回答
0

我也有这个问题。我通过将登录帐户更改为本地系统帐户使其工作。在我的项目中,我将其设置为作为本地服务帐户运行。因此,当我安装它时,默认情况下它使用的是本地服务。我正在使用 .net 2.0 和 VS 2005。所以安装 .net 1.1 SP1 不会有帮助。

于 2009-03-03T20:10:31.473 回答
0

本地系统帐户和本地服务都不适用于我,然后我将其设置为网络服务,这工作正常。

于 2009-07-20T13:33:17.883 回答
0

就我而言,由于真正的错误,我遇到了这个麻烦。在调用服务构造函数之前,成员变量的一个静态构造函数失败了:

    private static OracleCommand cmd;

    static SchedTasks()
    {
        try
        {
            cmd = new OracleCommand("select * from change_notification");
        }
        catch (Exception e)
        {
            Log(e.Message); 
            // "The provider is not compatible with the version of Oracle client"
        }
    }

通过添加 try-catch 块,我发现由于错误的 oracle 版本而发生异常。安装正确的数据库解决了这个问题。

于 2011-02-21T02:52:17.393 回答
0

在我们的案例中,我们引用了事件查看器并收到错误说明机器配置不是格式良好的 XML,因此我们调查并发现有人在我们删除的元素之一中放置了双 << 尖括号,这解决了我们的问题

于 2022-01-18T12:23:09.357 回答
0

这对我有用。基本上确保登录用户设置为正确的。但是,这取决于帐户基础架构的设置方式。在我的示例中,它使用 AD 帐户用户凭据。

在启动菜单搜索框中搜索“服务”-在“服务”中找到所需的服务-右键单击并选择“登录”选项卡-选择“此帐户”并输入所需的内容/凭据-确定并照常启动服务

在此处输入图像描述

于 2016-03-23T10:26:53.797 回答
0

我遇到了同样的问题并尝试了上述所有方法,但问题仍然存在,然后我尝试了以下解决方案,它对我有用,如果您尝试了所有方法,您也可以尝试这个,也许它会解决您的问题:

  1. 转到文件夹:~\bin\Debug,
  2. 备份所有文件,然后删除所有文件,
  3. 重新构建应用程序,然后在服务器上部署新文件,
  4. 现在尝试运行该服务。
于 2021-09-02T08:44:28.370 回答
0

如果您有用于测试的 windows 窗体,请确保启动对象仍然是服务而不是 windows 窗体

于 2016-04-04T15:10:53.620 回答
0
  1. 在发布模式下构建项目。
  2. 将所有 Release 文件夹文件复制到源路径。
  3. 在管理访问中使用命令提示符窗口执行 Window 服务。
  4. 永远不要从源路径中删除文件。

至少这对我有用。

于 2016-08-25T08:19:21.620 回答
0

我们将 Log4Net 配置为记录到数据库表。该表变得如此之大,以至于服务在尝试记录消息时超时。

于 2016-06-15T17:48:35.713 回答
0

在我的情况下,它是AD中用户帐户的权限。正确设置后,它可以完美运行。

于 2018-08-02T12:14:42.603 回答
0

我的问题是服务程序找不到第三方 dll。将 dll 的路径添加到系统 PATH 中解决了这个问题。

于 2022-02-02T11:52:46.537 回答
0

以管理员身份打开服务窗口,然后尝试启动服务。这对我有用。

于 2016-08-22T04:47:13.137 回答
0

发布版本对我不起作用,但是,我查看了事件查看器和应用程序日志,发现 Windows 服务在尝试创建事件日志时抛出了安全异常。我通过使用管理访问手动添加事件源来解决此问题。

我遵循了微软的这份指南:

  • 打开注册表编辑器,运行 --> regedit
  • 找到以下注册表子项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application
  • 右键单击应用程序子项,指向新建,然后单击项。
  • 键入 Windows 服务中使用的事件源名称作为键名。
  • 关闭注册表编辑器。
于 2017-03-21T14:40:08.650 回答