【问题标题】:C# Windows Service Opening File For UserC# Windows 服务为用户打开文件
【发布时间】:2017-02-02 08:52:49
【问题描述】:

这是我第一次创建 Windows 服务,我正在尝试为当前登录用户打开一个可执行文件,而该服务作为本地运行服务,本地系统, 但我遇到的是 ExecutableSYSTEM 用户身份运行,但没有显示给User 我的意思是进程在 SYSTEM 用户下Running 没有为 显示 Window >登录用户

如果我的 Windows 服务作为 本地服务 运行,那么 可执行文件 似乎无法运行。任务管理器中没有生命迹象。

我已尝试查找我的问题并尝试了以下解决方案:

  1. Process.Start("FileName");
  2. File.Open("FileName", FileMode.Open);什么都没做! (任务管理器中没有生命迹象)
  3. ProcessStartInfo("FileName") with Verb = "run as";没有改变任何东西(以 SYSTEM 身份运行)
  4. 从命令提示符尝试了 shell 命令:Process.Start("run as (Forgot the entire command line I type)");什么都没做! (任务管理器中没有生命迹象)
  5. ProcessStartInfo("FileName") with Username = "User" without Password;什么都没做! (任务管理器中没有生命迹象)

我确实认为解决方案 4 和 5 不起作用,因为需要 密码,但根据 Microsoft Post 关于 Local System 的信息说 SYSTEM 不需要 Password 来访问 UserImpersonation),但我不明白什么Impersonation 确实是,它似乎与 Win API Natives 有什么关系。

我认为可执行文件窗口实际上是在Executable运行时显示给SYSTEM的。不是当前登录的用户

现在:

  1. 如果没有 WinAPI Natives,我的问题是否有解决方案
  2. 如果需要本地人,您能否也尝试向我解释一下?发布代码时?我只了解 WinAPIHandles,这就是我真正了解的全部。
  3. 这可以在 本地系统 运行服务上实现吗?因为我的服务专注于做系统管理?而不是本地服务
  4. 是否可以在 C# 编程语言中完成所有这些操作?

PS:我正在进行的项目是我公司的系统管理工具包。对于未来的项目。
PS2:如果您需要更多信息,请告诉我,我会经常查看此帖子。
PS3:如果您发现任何语法错误,请原谅我的英语。

【问题讨论】:

  • PS4:我的操作系统是 Windows 10
  • StartInfo 和 File.Open() 不会启动进程,也许在谷歌上搜索一下会有所帮助。
  • 我确实做了很多谷歌搜索,但我还找不到解决问题的方法,而且我知道 StartInfo 应该在 Process.Start 中。如果我能找到解决问题的方法,我会尽快发布。
  • 请更详细地描述您真正想要实现的目标。您要启动应用程序吗?是否要打开应用程序映射到文件类型的文件?我不清楚你的目标是什么。

标签: c# service local


【解决方案1】:

解决方案代码

using (TaskService taskService = new TaskService())
            {
                TaskDefinition taskDefinition = taskService.NewTask();
                taskDefinition.RegistrationInfo.Description = "Does something";
                taskDefinition.RegistrationInfo.Author = "SYSTEM";

                taskDefinition.Principal.DisplayName = "Testing Display Task Name C#";
                taskDefinition.Principal.RunLevel = TaskRunLevel.Highest;
                taskDefinition.Principal.GroupId = "Administrators";
                taskDefinition.Principal.UserId = "ACCOUNT";
                taskDefinition.Principal.LogonType = TaskLogonType.InteractiveToken;

                taskDefinition.Settings.AllowDemandStart = true;
                taskDefinition.Settings.AllowHardTerminate = true;
                taskDefinition.Settings.DisallowStartIfOnBatteries = false;
                taskDefinition.Settings.DisallowStartOnRemoteAppSession = true;
                taskDefinition.Settings.Hidden = false;
                taskDefinition.Settings.RestartCount = 0;
                taskDefinition.Settings.RunOnlyIfIdle = false;
                taskDefinition.Settings.RunOnlyIfNetworkAvailable = false;
                taskDefinition.Settings.StartWhenAvailable = true;
                taskDefinition.Settings.StopIfGoingOnBatteries = false;
                taskDefinition.Settings.Volatile = false;
                taskDefinition.Settings.WakeToRun = false;

                taskDefinition.Actions.Add(new ExecAction("notepad.exe"));

                const string taskName = "Testing TASK";
                taskService.RootFolder.RegisterTaskDefinition(taskName, taskDefinition);

                taskService.FindTask("Testing TASK").Run();

            }

解决方案是Task Scheduler API,我不想解释太多,但这很简单。

为此,您需要访问 Task Scheduler API,但大部分代码是 Unmanaged(c++),我们不希望这样。我们需要 C# Managed Task Scheduler API,为此我们需要下载此 Nuget 包LINK

这将使我们能够使用非常好的 ManagedDocumented 代码访问 C# 中的 Task Scheduler API。如果您不知道 Task Scheduler API 是什么,请查看它非常容易理解。

然后我们编写我们的TaskRun它,它会去Start/Open/Execute指定的Application > 在指定的 User 上使用 UAC,如果需要,无需提示。就这么简单! 不需要本地人

现在要获得更详细的解释,让我们从答案顶部获取我们的示例解决方案代码。在 RegisterInfo.Author 我们指定哪个 User 正在创建这个 Task,在这种情况下我们写 SYSTEM 因为我们的服务是本地系统。然后在 Principal.GroupID 中写入我们要执行文件的 User 所在的 Group。在我的情况下,User 可以说是 Administrator,这意味着它将在 Administrators 组中。然后最后在 Principal.UserId 我们写而不是 ACCOUNT 我们想要 Start/Open/Execute 文件的 Administrators Group 中的哪个用户让我们说约翰。而已!如果你运行代码,它会在那个用户上打开notepad.exe!。如果有人想改进我的答案,我不想解释太多,但这是这样做的方法。

PS:请记住,您需要至少具有管理员权限才能创建任务PS2:有关此 C# Managed Task Scheduler API 的非常好的文档,请查看LINK

就是这样!稍后我可能会改进这个答案,我现在没有太多时间。

【讨论】:

  • PS3:在您创建该任务并完成其工作后,推荐 删除它!除非您打算多次使用它
  • 如何使用dispose()方法删除任务?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 2018-11-11
相关资源
最近更新 更多