我最近继承了一些作为Windows服务运行的应用程序,我在向它们提供gui(可以从系统托盘中的上下文菜单访问)时遇到问题。
我们需要为Windows服务使用gui的原因是为了能够重新配置Windows服务的行为而无需停止/重新启动。
我的代码在调试模式下工作正常,我得到了上下文菜单,一切都正常等等。
当我使用命名帐户(即非本地系统帐户)通过“installutil”安装服务时,服务运行正常,但不显示系统托盘中的图标(我知道这是正常行为,因为我没有“与桌面交互”选项)。
这是问题所在 - 当我选择“LocalSystemAccount”选项,并检查“与桌面交互”选项时,该服务需要AGES启动,没有明显的原因,我只是继续
无法在本地计算机上启动...服务。
错误1053:服务未及时响应启动或控制请求。
顺便提一下,我通过注册表黑客将Windows服务超时从默认的30秒增加到2分钟(请参阅http://support.microsoft.com/kb/824344,在第3节中搜索TimeoutPeriod),但服务启动仍然超时。
我的第一个问题是 - 为什么“本地系统帐户”登录比服务使用非LocalSystemAccount登录时要长得多,导致Windows服务超时?这两者在启动时会产生如此不同的行为有什么不同?
其次 - 退后一步,我想要实现的只是一个提供配置gui的Windows服务 - 我很乐意使用非本地系统帐户运行(具有指定用户/ pwd),如果我可以让服务与桌面交互(也就是说,系统托盘中有一个上下文菜单)。这是可能的,如果是这样的话?
对上述问题的任何指示都将不胜感激!
答案 0 :(得分:68)
在打了几天这个消息之后,一位朋友告诉我你必须使用Release版本。当我InstallUtil Debug构建时,它会给出此消息。发布版本开始很好。
答案 1 :(得分:29)
如果您继续尝试让您的服务直接与用户的桌面交互,那么您将失败:即使在最好的情况下(即“在Vista之前”),这也是非常棘手的。
Windows内部管理多个window stations,每个application-defined Service Control Manager commands都有自己的桌面。分配给在给定帐户下运行的服务的窗口站与登录的交互用户的窗口站完全不同。跨窗口站访问一直是不受欢迎的,因为它存在安全风险,但是之前的Windows版本允许一些例外,这些已经在Vista和更高版本的操作系统中被淘汰。
您的服务在启动时挂起的最可能原因是因为它尝试与不存在的桌面交互(或假设Explorer在系统用户会话中运行,而实际情况并非如此),或等待来自一个看不见的桌面。
针对这些问题的唯一可靠修复是从服务中删除所有UI代码,并将其移动到在交互式用户会话内运行的单独可执行文件(可执行文件可以使用全局启动例如,启动组。
您可以使用任何RPC机制实现UI代码与服务之间的通信:命名管道可以很好地实现此目的。如果您的通信需求很少,使用disable the verification of the Authenticode signature at load time in order to create Publisher evidence也可能会有所帮助。
在UI和服务代码之间实现这种分离需要一些努力:但是,这是使事情可靠地工作的唯一方法,并且将来会很好地为您服务。
ADDENDUM,2010年4月:由于这个问题仍然很受欢迎,这里有一种方法可以解决导致“服务没有响应......”错误的另一种常见情况,包括不提供.NET服务的问题尝试任何有趣的事情,比如与桌面交互,但做使用Authenticode签名的程序集:{{3}},将以下元素添加到.exe.config文件中:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
发布者证据是一种很少使用的代码访问安全性(CAS)功能:只有在您的服务实际依赖于PublisherMembershipCondition的情况下,禁用它才会导致问题。在所有其他情况下,它将使永久或间歇性启动失败消失,不再需要运行时进行昂贵的证书检查(包括撤销列表查找)。
答案 2 :(得分:18)
我遇到了这个问题,因为运行我的服务的盒子上缺少框架。该框具有.NET 4.0,该服务是在.NET 4.5之上编写的。
我在盒子上安装了以下下载,重新启动,服务启动正常: http://www.microsoft.com/en-us/download/details.aspx?id=30653
答案 3 :(得分:12)
要调试服务的启动,请将以下内容添加到服务的OnStart()
方法的顶部:
while(!System.Diagnostics.Debugger.IsAttached) Thread.Sleep(100);
这将停止服务,直到您使用Debug手动附加Visual Studio调试器 - &gt;附加到流程...
注意:通常,如果您需要用户与您的服务进行交互,最好将GUI组件拆分为在用户登录时运行的单独Windows应用程序。然后使用类似于命名管道或其他形式的IPC,用于在GUI应用程序和您的服务之间建立通信。这实际上是唯一方式,这在Windows Vista中是可行的。
答案 4 :(得分:5)
我在这里盲目拍摄,但我经常发现服务初创公司的长时间延迟是由网络功能超时直接或间接造成的,通常是在查找帐户SID时要联系域控制器 - 这种情况非常发生通常是通过GetMachineAccountSid()
间接地通过{1}来实现,因为RPC子系统会调用该函数。
有关如何在这种情况下进行调试的示例,请参阅Mark Russinovich博客上的The Case of the Process Startup Delays。
答案 5 :(得分:5)
在OnStart方法中的服务类中不做大量操作,OS期望运行服务的时间很短,使用线程启动运行你的方法:
protected override void OnStart(string[] args)
{
Thread t = new Thead(new ThreadStart(MethodName)); // e.g.
t.Start();
}
答案 6 :(得分:4)
如果您在服务中使用如下调试代码,可能会出现问题。
#if(!DEBUG)
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new EmailService()
};
ServiceBase.Run(ServicesToRun);
#else
//direct call function what you need to run
#endif
要解决此问题,在构建Windows服务时,请删除#if条件,因为它没有按原样运行。
请使用参数调试模式,如下所示。
if (args != null && args.Length > 0)
{
_isDebug = args[0].ToLower().Contains("debug");
}
答案 7 :(得分:3)
就我而言,问题是缺少.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>
答案 8 :(得分:3)
我遇到的问题与我写的服务有关。它工作正常,然后有一天我开始在启动错误上获得超时。它发生在一个&amp; /或Release和Debug中,具体取决于发生了什么。我已经从System.Diagnostics实例化了一个EventLogger,但是在Logger能够编写之前,我所看到的任何错误都必须发生......
如果您不知道在哪里查找EventLog,在VS中您可以在服务器资源管理器下转到您的计算机。除了我的服务之外,我开始在其他一些EventLog中闲逛。在Application - .NETRuntime下,我发现错误日志与启动时的错误有关。基本上,我的服务构造函数中有一些例外(一个在EventLog实例设置中被证明是一个例外 - 这解释了为什么我在服务事件日志中看不到任何日志)。在之前的版本中,显然存在其他错误(导致我在EventLog设置中进行更改导致错误)。
长话短说 - 超时的原因可能是由于各种异常/错误,但使用运行时事件日志可能只是帮助您弄清楚发生了什么(特别是在一个构建工作但另一个不工作的情况下)。
希望这有帮助!
答案 9 :(得分:2)
尝试运行你的exe文件。我遇到了同样的问题,但是当我通过双击exe文件直接运行它时,我得到了一个关于.Net框架版本的消息,因为我发布了一个没有安装在目标机器上的框架的服务项目。
答案 10 :(得分:2)
当程序集中缺少某些引用并且通常绑定在运行时失败时,通常会发生此问题。
调试Thread.Sleep(1000)
中的main()
。并在下一行执行中设置一个断点。
然后启动该过程并在启动时将调试器附加到进程。在达到断点后按f5。它将抛出缺少程序集或引用的异常。
希望这会解决此错误。
答案 11 :(得分:2)
我有这个问题,花了大约一天时间来解决。对我来说问题是我的代码跳过了“主要内容”并有效地运行了几行然后完成。这给我造成了错误。它是一个安装Windows服务的C#控制台应用程序,只要它尝试使用ServiceController(sc.Run())运行它,那么它就会给我这个错误。
在我修改代码以转到主要内容后,它将运行预期的代码:
ServiceBase.Run(new ServiceHost());
然后它停止了出现。
正如很多人已经说过的那样,错误可能是任何事情,人们提供的解决方案可能会或可能不会解决。如果他们没有解决它(比如Release而不是Debug,在你的配置中添加generatePublisherEvidence = false等),那么问题可能在于你自己的代码。
尝试在不使用sc.Run()的情况下运行代码(即使代码运行sc.Run()将执行)。
答案 12 :(得分:2)
安装服务的调试版本并将调试器附加到服务以查看正在发生的事情。
答案 13 :(得分:2)
我想在这里回复mdb的评论。不要走这条路。您的服务不应该有UI ...“没有用户交互”就像服务的定义功能。
如果需要配置服务,请编写另一个应用程序,该应用程序编辑服务在启动时读取的相同配置。但要使其成为一个独特的工具 - 当您想要启动服务时,您可以启动该服务。如果要对其进行配置,请运行配置工具。
现在,如果您需要对服务进行实时监控,那么这有点棘手(当然,我希望通过服务实现这一点)。现在你谈论的是必须使用进程间通信和其他麻烦。
最糟糕的是,如果您需要用户互动,那么您在这里就会有真正的脱节,因为服务不会与用户互动。
在你的鞋子里我会退后一步,问为什么这需要服务?并且为什么需要用户互动??
这两个要求非常不相容,应该引发警报。
答案 14 :(得分:2)
我遇到了这个问题,它让我疯了两天...... 如果您的问题与我的相似:
我在Windows服务中设置了“用户设置”,因此该服务可以进行自我维护,而无需停止和启动服务。嗯,问题在于“用户设置”,其中这些设置的配置文件保存在service-exe文件版本下运行Windows服务的用户的用户配置文件下的文件夹中。
由于某种原因,此文件夹已损坏。我删除了文件夹和服务开始像往常一样愉快地工作......
答案 15 :(得分:2)
复制发行版DLL或从发布模式而不是调试模式获取dll并将其粘贴到安装文件夹,它应该可以正常工作
答案 16 :(得分:1)
将127.0.0.1 crl.microsoft.com添加到“Hosts”文件解决了我们的问题。
答案 17 :(得分:1)
我的问题是由于Windows服务配置中提到的目标框架是
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
这个.Net版本不支持我试图安装Windows服务的服务器。
改变哪些,我能够解决问题。
答案 18 :(得分:1)
答案 19 :(得分:0)
在我的情况下,这是AD中 user 帐户的权限。 正确设置后,它可以完美工作。
答案 20 :(得分:0)
本地系统帐户和本地服务都不适用于我,然后我将其设置为网络服务,这很好。
答案 21 :(得分:0)
发布版本对我不起作用,但是,我查看了我的事件查看器和应用程序日志,发现Windows服务在尝试创建事件日志时抛出了安全异常。我通过管理访问手动添加事件源来修复此问题。
我遵循了Microsoft的指南:
答案 22 :(得分:0)
我遇到了类似的问题,我停了下来
我的问题不是由于任何错误。 我有一个BlockingCollection.GetConsumingEnumerable()。这导致Windows服务等待。
答案 23 :(得分:0)
以管理员身份打开服务窗口,然后尝试启动该服务。这对我有用。
答案 24 :(得分:0)
我们已将Log4Net配置为记录到数据库表。该表已经变得如此之大,以至于该服务正在尝试记录消息。
答案 25 :(得分:0)
如果您有用于测试的Windows窗体,请确保启动对象仍然是服务而不是窗体
答案 26 :(得分:0)
这对我有用。基本上确保登录用户设置为正确的用户。但是,这取决于帐户基础结构的设置方式。在我的示例中,它使用的是AD帐户用户凭据。
在启动菜单搜索框中搜索“服务” -In Services找到所需的服务 - 右键单击并选择“登录”选项卡 - 选择“此帐户”并输入所需的内容/凭据 - 然后像往常一样启动服务
答案 27 :(得分: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给了我很多帮助。
答案 28 :(得分:0)
我也有这个问题。我通过将登录帐户更改为本地系统帐户使其工作。在我的项目中,我将其设置为以本地服务帐户运行。因此,当我安装它时,默认情况下它使用本地服务。我正在使用.net 2.0和VS 2005.所以安装.net 1.1 SP1不会有帮助。
答案 29 :(得分: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版本而发生了异常。安装正确的数据库解决了这个问题。
答案 30 :(得分:-1)
至少这对我有用。