我有一项监视文件夹并执行操作的服务。
这很好用。
但是,如果我故意在创建文件时调用的事件方法内引发异常,则我的服务将停止。我以为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。
该服务以本地系统用户的身份运行。
答案 0 :(得分:1)
Local System 帐户没有privileges与您要尝试与Service Control Manager(SCM)进行交互。
您需要使用具有这些特权的其他帐户来运行服务。
如果必须以本地系统身份运行,那么建议您将SCM本身配置为重新启动服务。无论如何,大多数系统管理员都会喜欢这种方式,因为他们可以控制发生的情况。这是一个非编程解决方案。
答案 1 :(得分:0)
它说“此操作可能还需要其他特权”,但这不是应该的,因为您说它正在以管理员特权运行,但是仍然可以尝试一下。
转到添加新项并将应用程序清单文件添加到您的项目
更改
<requestedExecutionLevel level="isInvoker" uiAccess="false" />
收件人
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
这可能会解决您的问题,请确保您运行应用程序的发行版而不是调试。