事件发生错误时重启服务C#

时间:2018-07-26 16:37:36

标签: c# windows-services

我有一项监视文件夹并执行操作的服务。

这很好用。

但是,如果我故意在创建文件时调用的事件方法内引发异常,则我的服务将停止。我以为Windows会在停止时自动尝试再次启动服务,但事实并非如此。

有几个示例可以重启我可以使用的服务,但是我只是想知道我是否在这里遗漏了一些明显的东西?

似乎我需要在整体try / catch块中放入一些内容才能重新启动服务?

这是设置文件夹监视程序的方法:

    public void Start()
    {
        var setting = ConfigurationManager.AppSettings["FolderToMonitor"];
        var path = string.IsNullOrEmpty(setting) ? "c:\\temp\\spreadsheets": setting;

        var processedPath = path + "\\Processed";
        Directory.CreateDirectory(processedPath);

        var errorsPath = path + "\\Errors";
        Directory.CreateDirectory(errorsPath);

        _watcher = new FileSystemWatcher
        {
            Path = path,
            NotifyFilter = NotifyFilters.Attributes |
                           NotifyFilters.CreationTime |
                           NotifyFilters.DirectoryName |
                           NotifyFilters.FileName |
                           NotifyFilters.LastAccess |
                           NotifyFilters.LastWrite |
                           NotifyFilters.Security |
                           NotifyFilters.Size,
            Filter = "*.*",
            EnableRaisingEvents = true
        };

        _watcher.Created += OnFileCreated;
    }

创建文件后,将调用此事件

   private void OnFileCreated(object sender, FileSystemEventArgs e)
   {
     while (!IsFileReady(e.FullPath))
     {
     }

     Process(e.FullPath);
  }

我现在故意在抛出异常:

    public virtual void Process(string filename)
    {
        var path = Path.GetDirectoryName(filename);
        var processedPath = path + "\\Processed";            
        var errorsPath = path + "\\Errors";

        var filenameOnly = Path.GetFileName(filename);

        try
        {
            ReadFile(filename);

            if (filename.Contains("hello"))
            {
                throw new Exception("TEST ERRROR");
            }
        }
        catch (Exception e)
        {
            Log.Error(e, "Error processing file");
            File.Move(filename ?? throw new InvalidOperationException(), $"{errorsPath}\\{filenameOnly}");

            throw;
        }

        Log.Information($"File processed {filename}.  Moved to processed folder");
        File.Move(filename ?? throw new InvalidOperationException(), $"{processedPath}\\{filenameOnly}");
    }

如果我尝试使用以下代码自行重启服务

var service = ServiceController.GetServices("My Service Name").FirstOrDefault();
            if (service?.Status == ServiceControllerStatus.Stopped)
            {
                service.Start();
            }

我收到错误

'Cannot open Service Control Manager on computer 'My Service Name'. This operation might require other privileges.'

我已经检查了两倍和三倍-我的服务名称正确。我也在管理员模式下运行Visual Studio。

该服务以本地系统用户的身份运行。

2 个答案:

答案 0 :(得分:1)

Local System 帐户没有privileges与您要尝试与Service Control Manager(SCM)进行交互。

您需要使用具有这些特权的其他帐户来运行服务。

如果必须以本地系统身份运行,那么建议您将SCM本身配置为重新启动服务。无论如何,大多数系统管理员都会喜欢这种方式,因为他们可以控制发生的情况。这是一个非编程解决方案。

答案 1 :(得分:0)

它说“此操作可能还需要其他特权”,但这不是应该的,因为您说它正在以管理员特权运行,但是仍然可以尝试一下。

转到添加新项并将应用程序清单文件添加到您的项目

更改

 <requestedExecutionLevel level="isInvoker" uiAccess="false" />

收件人

 <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

这可能会解决您的问题,请确保您运行应用程序的发行版而不是调试。