C# Windows服务暂停

C# Windows服务暂停,c#,windows-services,google-calendar-api,xdebug,C#,Windows Services,Google Calendar Api,Xdebug,我有一个windows服务,它应该以一定的间隔运行(目前为测试目的设置为1分钟),从我们的数据库中获取数据,然后将信息上传到我们的谷歌日历。在调试模式下,一切运行正常,但是当windows服务在我的PC上自行运行时,它似乎在“Inside StartGoogleCalendar”事件日志条目处暂停。为什么它在调试模式下运行良好,但在生产模式下却会暂停?我做错什么了吗?下面是代码 protected override void OnStart(string[] args) { EventL

我有一个windows服务,它应该以一定的间隔运行(目前为测试目的设置为1分钟),从我们的数据库中获取数据,然后将信息上传到我们的谷歌日历。在调试模式下,一切运行正常,但是当windows服务在我的PC上自行运行时,它似乎在“Inside StartGoogleCalendar”事件日志条目处暂停。为什么它在调试模式下运行良好,但在生产模式下却会暂停?我做错什么了吗?下面是代码

protected override void OnStart(string[] args)
{
    EventLog.WriteEntry("Service Started: " + DateTime.Now.ToLongDateString());
    _timer = new System.Timers.Timer(1 * 60 * 1000);
    _timer.Elapsed += new System.Timers.ElapsedEventHandler(fireGoogle);
    _timer.Start();
}

protected override void OnStop()
{
    EventLog.WriteEntry("Service Stopped: " + DateTime.Now.ToLongDateString());
}

private void fireGoogle(object sender, System.Timers.ElapsedEventArgs e)
{
    EventLog.WriteEntry("Firing Google: " + DateTime.Now.ToLongDateString());
    StartGoogleCalendar();
}

public void StartGoogleCalendar()
{
    try
    {
        EventLog.WriteEntry("Inside StartGoogleCalendar");
        authorization Auth = new authorization();
        EventLog.WriteEntry("Done with Auth");
        calendar ipamCal = new calendar();
        EventLog.WriteEntry(Auth.EventLogEvent());
        EventLog.WriteEntry("GAPI Calendar Schedule complete");
    }
    catch (Exception ex)
    {
        EventLog.WriteEntry(ex.Data.ToString() + ": INNER EXCEPTION: " + ex.InnerException.ToString() + " - GENERAL MESSAGE: " + ex.Message.ToString() + " - SOURCE: " + ex.Source.ToString() );
    }
}
以下是“授权”代码(client_secrets.json确实存在,因为它在调试模式下工作):

private static EventLog\u el=new EventLog();
公共授权()
{
globals.scopes=新列表();
_authCredentials();
}
私有void_authCredentials()
{
globals.scopes.Add(“https://www.googleapis.com/auth/calendar");
尝试
{
_el.WriteEntry(“内部认证”);
使用(FileStream _stream=newfilestream(“client_secrets.json”、FileMode.Open、FileAccess.Read))
{
_el.WriteEntry(“试图获取凭据”);
globals.userCredentials=GoogleWebAuthorizationBroker.AuthorizationAsync(GoogleClientSecrets.Load(_stream).Secrets,globals.scopes,“今天在IPAM”,CancellationToken.None,新文件数据存储(“calendar_new.dat”)。结果;
_el.WriteEntry(globals.userCredentials.Token.ToString());
}
_el.WriteEntry(“谷歌授权-成功”);
}
捕获(例外情况除外)
{{u el.WriteEntry(“谷歌授权-失败\r\n\tReason:+ex.InnerException.Message);}
}
公共字符串EventLogEvent()
{返回globals.eventLogEvents;}

您必须测试以下几项: 1/在windows系统中添加服务时,是否指定了整个执行路径 请使用命令行参阅。 SC CREATE“ServiceName”DisplayName=“Displaying Service Name”binpath=“C:\User\Service.exe”start=auto obj=“NT AUTHORITY\LocalService”

2/您用于启动服务的帐户是什么?权限是否正确? 请参考上一示例中的参数obj


3/目录和文件“client_secrets.json”的权限是多少当您在调试模式下运行服务时,它将在服务可执行文件的bin文件夹中查找文件。但是,当您以发布模式(即作为已安装的服务)运行它时,它将通过服务控制管理器运行,该管理器的工作文件夹为system32。您应该做的第一件事是将机密文件的路径放在.config文件中,然后通过文件的绝对路径(client_secrets.json)读取该路径以加载文件

其次,我不建议在windows事件日志中写入所有内容。您应该考虑使用Log4NET或类似的应用程序日志记录。< /P>
最后,您的计时器现在是asyn timer,想象一下,如果您的进程花费的时间超过了您的计时器间隔,那么它将在第一个请求完成之前执行另一个请求。你应该考虑让你的计时器同步

人们查看你的服务权限的建议看起来是有效的。 我想补充一点,你的两个catch语句都可能失败。如果没有innerException怎么办?:)


我不熟悉谷歌的认证模块,但如果你能首先针对一个更具体的异常,这可能会帮助你弄清服务失败的原因。

我可以想到两件事:

a) 检查运行服务的帐户是否具有访问internet的足够权限

b) 我会创建一个单独的线程并在那里工作。例如:

    public partial class Service1 : ServiceBase
    {
        private Thread _thread;

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            _thread = new Thread(DoWork);
            _thread.Start();
        }

        private void DoWork()
        {
            // Write your code here...
            File.WriteAllText(@"C:\Test123.txt","hello world!");
        }

        protected override void OnStop()
        {
        }
    }

基本上,我们不应该在side OnStart()中执行长时间运行的任务。我希望这会有所帮助。

只是一个想法,它可能与您的问题无关。 我看到您每分钟都在创建授权对象,并向其添加相同的作用域url。我不知道您的globals对象是否被清除,您可能在打开web请求连接时遇到某种线程问题。 同样的道理,您正在一次又一次地添加相同的凭据

将您的授权对象转换为singleton,看看它是否可以工作,或者不使用globals,并在对象超出范围时清理它

我也有类似的问题,从窗口(而不是窗口服务)自动调用web时,它会引发线程问题,并且会挂起


2c,通常从对象构造函数调用任何函数都不是一个好主意。

这个问题与.dat文件由于google身份验证而变得无效有关。

您的授权代码在做什么?根据您的请求添加了授权代码,请仔细查看文件数据存储在%appData%目录中为您存储一个名为calendar_new.dat的文件。您是否将windows服务设置为以您的用户帐户运行?它可能无法访问它。当要通过windows服务运行某些内容时,我通常使用服务帐户。windows服务设置为使用本地系统帐户,serviceprocessinstaller帐户属性设置为LocalService当您在弹出的调试环境中运行它并要求您对其进行授权时。这将您的授权保存在%appData%目录中。您的windows服务将无法访问该文件。如果你不明白,我建议我们把这个移到聊天上。
    public partial class Service1 : ServiceBase
    {
        private Thread _thread;

        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            _thread = new Thread(DoWork);
            _thread.Start();
        }

        private void DoWork()
        {
            // Write your code here...
            File.WriteAllText(@"C:\Test123.txt","hello world!");
        }

        protected override void OnStop()
        {
        }
    }