【问题标题】:How to start a Windows service using powershell in a .net core application?如何在 .net 核心应用程序中使用 powershell 启动 Windows 服务?
【发布时间】:2021-01-25 19:22:50
【问题描述】:

我有一个 .net 应用程序,我希望能够启动和停止在同一台计算机上运行的 Windows 服务。我能够毫无问题地使用 get-service 拉回服务的状态,但是执行 start-service 不起作用。没有错误,只是什么都不做。我首先尝试了这个,没有使用 async Invoke 选项,这样它看起来更像底部的函数。本地调试时,不工作,不报错。

using System.Management.Automation;

        private async static Task EditService(string serviceName, string command)
        {
            using (PowerShell PowerShellInst = PowerShell.Create())
            {
                //PowerShellInst.AddCommand(command).AddParameter("Name", serviceName);
                //I tried surrounding serviceName in quotes (but it has no spaces)
                PowerShellInst.AddScript("Start-Service -Name " + serviceName);

                await PowerShellInst.InvokeAsync();
            }         
        }

获取服务状态(可行):

 public static string GetServiceStatus(string serviceName)
        {            

            using (PowerShell PowerShellInst = PowerShell.Create())
            {
                PowerShellInst.AddScript("Get-Service " + serviceName);

                Collection<PSObject> PSOutput = PowerShellInst.Invoke();

                if (PSOutput == null || PSOutput.Count == 0)
                    return "Unknown";
                else
                    return PSOutput.First().Properties["Status"].Value.ToString();                
            }            
        }

【问题讨论】:

  • 我要尝试的第一件事是对 Get-ServiceStart-Service 使用相同的语法,在 PowerShell 中两者都应该可以工作,但不确定在这个包装的场景中。所以只需删除Start-Service-Name 部分即可排除。
  • @PMental 这并没有什么不同,所以我们可以排除这种情况。我想知道这是否像转换器建议的答案那样是权限问题

标签: .net powershell windows-services


【解决方案1】:

听起来你没有权限,一种选择是设置执行策略

//in powershell
 powershell.AddCommand("Set-ExecutionPolicy").AddArgument("Unrestricted")
.AddParameter("Scope","CurrentUser");

//or using the command prompt like so:
 string powerShellCmd = "/c powershell -executionpolicy unrestricted C:\somePowerShellScript.ps1";
System.Diagnostics.Process.Start("cmd.exe",powerShellCmd);

你可以像这样获取当前用户

WindowsIndentity.GetCurrent().Name

可选择尝试新的 Host Builder,它是 .Net Core 原生的新增功能,即 没有 topshelf

 public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((context, config) =>
            {
                // configure the app here.
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });

【讨论】:

  • ExecutionPolicy 可以阻止脚本运行,但不区分不同的 CmdLets,也不阻止 shell 代码。如果 Get-Process 有效,那么 ExecutionPolicy 适合这种情况。
  • Host Builder 的东西对我来说有点希腊化,所以我将首先关注权限概念(并尝试命令提示符的想法),尽管我对此很好奇
  • 已解决 - 这是一个权限问题。 IIS 网站的应用程序池标识无法启动/停止服务,但是当我将其更改为具有管理员权限的服务帐户时,一切正常。我不必从这个答案中添加任何代码,这是我最初工作的。但是我发现如果我不想使用 Powershell,ServiceController 类是另一个选择。
  • 您可以更改.AddParameter("Scope","CurrentUser"); 行并替换您的用户,它将在具有权限的用户下运行。很高兴它有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多