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