首页 > 解决方案 > 启动单击一次应用程序 - 未找到文件

问题描述

我有一个基本服务,将用于每 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\Start Menu\Programs\PubName\ProdName.appref-ms

为了启动文件,我有什么遗漏吗?

标签: c#clickonce

解决方案


Windows 服务是甚至在用户登录其帐户之前就会运行的程序。这是 Windows 服务的目的,根据这个定义,您无法访问特定的用户环境变量(如 %AppData%),因为不在用户会话中,因此如果您将地址写入.txt 你会看到结果。

Windows 服务(根据您的定义)将由 LocalSystem、LocalService 或 NetworkService 运行。转到 TaskManager->Services->Open Services 并观看Log On As专栏。

因此,您必须使用可通过您的服务访问的通用路径。

最可怕的解决方案是强制您的服务等待用户登录并冒充他的令牌。

我会宁愿选择一个更好的地方。

有一种方法可以在 VisualStudio中调试和查看您的服务错误(在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);
 }

如果您以这种方式调试项目,您将看到您的服务按预期工作!!!


推荐阅读