56

在远程 Windows 系统上重新启动服务的最简单的编程方法是什么?只要不需要人机交互,语言或方法就无关紧要。

4

11 回答 11

98

从 Windows XP 开始,您可以使用sc.exe它与本地和远程服务进行交互。安排一个任务来运行一个类似于这样的批处理文件:

sc \\服务器停止服务
sc \\server 启动服务

确保任务在目标服务器上具有特权的用户帐户下运行。

psservice.exe来自Sysinternals 的 PSTools也可以完成这项工作:

psservice \\服务器重启服务
于 2008-11-05T20:01:48.830 回答
13

描述:SC 是一个命令行程序,用于与 NT 服务控制器和服务进行通信。用法:sc [命令] [服务名称] ...

    The option <server> has the form "\\ServerName"
    Further help on commands can be obtained by typing: "sc [command]"
    Commands:
      query-----------Queries the status for a service, or
                      enumerates the status for types of services.
      queryex---------Queries the extended status for a service, or
                      enumerates the status for types of services.
      start-----------Starts a service.
      pause-----------Sends a PAUSE control request to a service.
      interrogate-----Sends an INTERROGATE control request to a service.
      continue--------Sends a CONTINUE control request to a service.
      stop------------Sends a STOP request to a service.
      config----------Changes the configuration of a service (persistant).
      description-----Changes the description of a service.
      failure---------Changes the actions taken by a service upon failure.
      qc--------------Queries the configuration information for a service.
      qdescription----Queries the description for a service.
      qfailure--------Queries the actions taken by a service upon failure.
      delete----------Deletes a service (from the registry).
      create----------Creates a service. (adds it to the registry).
      control---------Sends a control to a service.
      sdshow----------Displays a service's security descriptor.
      sdset-----------Sets a service's security descriptor.
      GetDisplayName--Gets the DisplayName for a service.
      GetKeyName------Gets the ServiceKeyName for a service.
      EnumDepend------Enumerates Service Dependencies.

    The following commands don't require a service name:
    sc <server> <command> <option>
      boot------------(ok | bad) Indicates whether the last boot should
                      be saved as the last-known-good boot configuration
      Lock------------Locks the Service Database
      QueryLock-------Queries the LockStatus for the SCManager Database

示例:sc 启动 MyService

于 2008-11-05T20:04:45.097 回答
4

如果它不需要人工交互,这意味着不会有 UI 调用此操作,我假设它会在某个设定的时间间隔重新启动?如果您可以访问机器,您可以设置一个计划任务以使用旧的 NET STOP 和 NET START 执行批处理文件

net stop "DNS Client"
net start "DNS client"

或者如果你想更复杂一点,你可以试试Powershell

于 2008-11-05T20:13:21.333 回答
2

服务将进入“停止挂起”的情况很多。操作系统会抱怨它“无法停止服务 xyz”。如果您想绝对确保服务已重新启动,您应该终止该进程。您可以通过在 bat 文件中执行以下操作来做到这一点

taskkill /F /IM processname.exe
timeout 20
sc start servicename

要找出与您的服务相关联的进程,请转到任务管理器-> 服务选项卡-> 右键单击​​您的服务-> 转到进程。

请注意,在您弄清楚为什么必须首先重新启动服务之前,这应该是一种解决方法。您应该寻找内存泄漏、无限循环和其他此类情况,以使您的服务变得无响应。

于 2015-06-15T14:18:24.513 回答
2

从 Powershell v3 开始,PSsessions 允许在远程计算机上运行任何本机 cmdlet

$session = New-PSsession -Computername "YourServerName"
Invoke-Command -Session $Session -ScriptBlock {Restart-Service "YourServiceName"}
Remove-PSSession $Session

请参阅此处了解更多信息

于 2015-09-11T11:35:00.090 回答
1

查看sysinternals以获取各种工具来帮助您实现该目标。例如 psService 将重新启动远程机器上的服务。

于 2008-11-05T20:00:43.590 回答
1

我推荐doofledorfer给出的方法。

如果您真的想通过直接 API 调用来实现,请查看OpenSCManager 函数。以下是获取机器名称和服务并停止或启动它们的示例函数。

function ServiceStart(sMachine, sService : string) : boolean;  //start service, return TRUE if successful
var schm, schs : SC_Handle;
    ss         : TServiceStatus;
    psTemp     : PChar;
    dwChkP     : DWord;
begin
  ss.dwCurrentState := 0;
  schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);  //connect to the service control manager

  if(schm > 0)then begin // if successful...
    schs := OpenService( schm,PChar(sService),SERVICE_START or SERVICE_QUERY_STATUS);    // open service handle, start and query status
    if(schs > 0)then begin     // if successful...
      psTemp := nil;
      if (StartService(schs,0,psTemp)) and (QueryServiceStatus(schs,ss)) then
        while(SERVICE_RUNNING <> ss.dwCurrentState)do begin
          dwChkP := ss.dwCheckPoint;  //dwCheckPoint contains a value incremented periodically to report progress of a long operation.  Store it.
          Sleep(ss.dwWaitHint);  //Sleep for recommended time before checking status again
          if(not QueryServiceStatus(schs,ss))then
            break;  //couldn't check status
          if(ss.dwCheckPoint < dwChkP)then
            Break;  //if QueryServiceStatus didn't work for some reason, avoid infinite loop
        end;  //while not running
      CloseServiceHandle(schs);
    end;  //if able to get service handle
    CloseServiceHandle(schm);
  end;  //if able to get svc mgr handle
  Result := SERVICE_RUNNING = ss.dwCurrentState;  //if we were able to start it, return true
end;

function ServiceStop(sMachine, sService : string) : boolean;  //stop service, return TRUE if successful
var schm, schs : SC_Handle;
    ss         : TServiceStatus;
    dwChkP     : DWord;
begin
  schm := OpenSCManager(PChar(sMachine),nil,SC_MANAGER_CONNECT);

  if(schm > 0)then begin
    schs := OpenService(schm,PChar(sService),SERVICE_STOP or SERVICE_QUERY_STATUS);
    if(schs > 0)then begin
      if (ControlService(schs,SERVICE_CONTROL_STOP,ss)) and (QueryServiceStatus(schs,ss)) then
        while(SERVICE_STOPPED <> ss.dwCurrentState) do begin
          dwChkP := ss.dwCheckPoint;
          Sleep(ss.dwWaitHint);
          if(not QueryServiceStatus(schs,ss))then
            Break;

          if(ss.dwCheckPoint < dwChkP)then
            Break;
        end;  //while
      CloseServiceHandle(schs);
    end;  //if able to get svc handle
    CloseServiceHandle(schm);
  end;  //if able to get svc mgr handle
  Result := SERVICE_STOPPED = ss.dwCurrentState;
end;
于 2008-11-05T20:11:58.437 回答
0
  1. 使用 openscmanager 打开服务控制管理器数据库
  2. 使用 EnumDependService() 获取依赖服务
  3. 使用 ChangeConfig() 停止所有相关服务,如果它们已启动,则向该函数发送 STOP 信号
  4. 停止实际服务
  5. 获取服务的所有服务依赖项
  6. 如果它们停止,则使用 StartService() 启动所有服务依赖项
  7. 开始实际服务

因此,您的服务将重新启动,注意所有依赖项。

于 2008-12-01T08:47:10.690 回答
0

我相信 PowerShell 现在在简单性方面胜过“sc”命令:

Restart-Service "servicename"
于 2016-07-12T23:35:42.727 回答
0

这就是我使用不同帐户远程重新启动服务时所做的事情

使用不同的登录名打开 CMD

runas /noprofile /user:DOMAIN\USERNAME cmd

使用 SC 停止和启动

sc \\SERVERNAME query Tomcat8
sc \\SERVERNAME stop Tomcat8
sc \\SERVERNAME start Tomcat8
于 2019-12-07T13:32:53.933 回答
0

如果您尝试在不同域的服务器上执行此操作,则需要比迄今为止大多数答案所建议的多一点,这就是我用来完成此操作的方法:

#Configuration
$servername = "ABC",
$serviceAccountUsername = "XYZ",
$serviceAccountPassword = "XXX"

#Establish connection
try {
    if (-not ([System.IO.Directory]::Exists('\\' + $servername))) {
        net use \\$servername /user:$serviceAccountUsername $serviceAccountPassword
    }
}
catch {
    #May already exists, if so just continue
    Write-Output $_.Exception.Message
}

#Restart Service
sc.exe \\$servername stop "ServiceNameHere"
sc.exe \\$servername start "ServiceNameHere"
于 2020-10-08T19:54:59.683 回答