我有一个基本服务,该服务将每隔X分钟运行一次ClickOnce应用程序,但是,当我运行Process.Start()时,我收到一个异常,找不到文件。
代码
private void OnElapsedTime(object source, ElapsedEventArgs e)
{
WriteToFile("Timer ticked");
CheckProcess(GetProcessName());
}
public void CheckProcess(string ProcessName)
{
WriteToFile(ProcessName);
try
{
Process.Start(ProcessName);
WriteToFile("It ran");
}
catch (Exception ex)
{
WriteToFile(ex.ToString());
}
}
public string GetProcessName()
{
string ProcessName = string.Concat("%AppData%\\Microsoft\\Windows\\Start Menu\\Programs\\", PublisherName, "\\", ProductName, ".appref-ms");
return ProcessName;
}
我收到的错误是:
%AppData%\Microsoft\Windows\Start Menu\Programs\PubName\ProdName.appref-ms
System.ComponentModel.Win32Exception (0x80004005): The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start(String fileName)
如果我运行在资源管理器中检索到的ProcessName,则该应用程序将成功启动。 ProcessName的值为:
C:\ Users \ xxx \ AppData \ Roaming \ Microsoft \ Windows \开始菜单\ Programs \ PubName \ ProdName.appref-ms
要启动文件,我是否缺少某些东西?
答案 0 :(得分:1)
Windows服务是甚至在用户登录其帐户之前也将运行的程序。这是Windows服务的目的,根据此定义,您无法访问特定的用户环境变量(如%AppData%),因为您不在用户会话中,因此您的地址将被转换为某些内容 Odd (奇数),如果将其写入.txt,则会看到结果。
Windows服务(根据您的定义)将由LocalSystem,LocalService或NetworkService运行。转到TaskManager->服务->打开服务,然后观察Log On As
列。
因此,您必须使用可通过服务访问的常规路径。
最可怕的解决方案是强制您的服务等待用户登录并假冒其令牌。
我更愿意选择一个更好的地方。
有一种方法可以在Visual Studio中调试并查看服务错误(在 UserSession 中)。 将Program.cs更改为:
static void Main()
{
#if DEBUG
var MainService = new MainService();
MainService.OnDebug();
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MainService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
并将OnDebug函数添加到您的服务:
public void OnDebug()
{
OnStart(null);
}
如果以这种方式调试项目,您将看到您的服务正在按预期工作!!!