Windows服务停滞

时间:2014-08-05 09:30:55

标签: c# windows-services google-calendar-api xdebug

我有一个应该以特定间隔运行的Windows服务(目前设置为1分钟用于测试目的)并从我们的数据库中获取数据,然后将信息上传到我们的Google日历。在调试模式下,一切运行正常,但是当Windows服务在我的PC上独立运行时,它似乎停留在内部StartGoogleCalendar" EventLog条目。为什么它在Debug模式下运行得很好但在生产模式下会停止?难道我做错了什么?以下是代码。

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 _el = new EventLog();
    public authorization()
    {
        globals.scopes = new List<string>();
        _authCredentials();
    }

    private void _authCredentials()
    {
        globals.scopes.Add("https://www.googleapis.com/auth/calendar");

        try
        {
            _el.WriteEntry("Inside _authcredentials");
            using (FileStream _stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))
            {
                _el.WriteEntry("Attempting to get credentials");
                globals.userCredentials = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(_stream).Secrets, globals.scopes, "Today-at-IPAM", CancellationToken.None, new FileDataStore("calendar_new.dat")).Result;
                _el.WriteEntry(globals.userCredentials.Token.ToString());
            }

            _el.WriteEntry( "Google Authorization - SUCCESS");
        }
        catch (Exception ex)
        { _el.WriteEntry( "Google Authorization - FAILED\r\n\tReason: " + ex.InnerException.Message); }
    }

    public String EventLogEvent()
    { return globals.eventLogEvents; }

6 个答案:

答案 0 :(得分:2)

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

其次我不建议在Windows事件日志中写入所有内容。您应该考虑使用log4net或类似方法进行应用程序日志记录。

最后你的计时器是asyn计时器,想象一下如果你的进程花费的时间长于你的计时器间隔,它将在第一个完成之前执行另一个请求。你应该考虑让你的计时器同步

答案 1 :(得分:1)

你必须测试几件事: 1 /当您在Windows系统中添加服务时,您已指定了整个执行路径 请参考命令行。 SC CREATE&#34; ServiceName&#34; DisplayName =&#34;显示服务名称&#34; binpath =&#34; C:\ User \ Service.exe&#34; start = auto obj =&#34; NT AUTHORITY \ LocalService&#34;

2 /您用于启动服务的帐户是什么,权限是对的? 请参考上一个例子中的参数obj。

3 /目录和文件&#34; client_secrets.json&#34;的权限是什么?

答案 2 :(得分:1)

人们建议查看与您的服务相关的权限看起来有效。 我想补充一点,你的两个catch语句都会失败。如果没有innerException会发生什么? :)

我不熟悉谷歌的身份验证模块 - 但是如果您可以首先定位更具体的例外,这可能有助于您了解服务失败的原因。

答案 3 :(得分:0)

我可以想到两件事:

a)检查运行该服务的帐户是否有足够的权限访问互联网。

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()
        {
        }
    }

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

答案 4 :(得分:0)

只是一个想法,它可能与您的问题无关。 我看到你每分钟都在创建你的授权对象,并为它添加相同的范围URL。我不知道你的全局对象是否被清除,你可能有某种线程问题打开web请求连接。 同样如此,您正在重复添加相同的凭据。

将您的授权对象转换为单身,看看它是否有效或不使用全局变量并在超出范围时清理对象。

我有一些类似的问题,从窗口(不是窗口服务)的一些自动调用web,它有线程引发问题,并将挂起。

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

答案 5 :(得分:0)

此问题与.dat文件因谷歌身份验证而变为无效有关。