【问题标题】:CMD command for starting a service remotely not running in code but runs on CMD用于远程启动服务的 CMD 命令不在代码中运行但在 CMD 上运行
【发布时间】:2019-06-28 13:12:54
【问题描述】:

我正在构建远程重新启动 Windows 服务的功能,但我在代码中构建的字符串命令没有返回所需的输出,在从 IDE 调试时复制相同的命令并在 CMD 上运行它成功执行。

我尝试从使用方法 Process cmdOutput Runtime.getRuntime().exec(command) 更改为 Process cmdOutput Runtime.getRuntime().exec(command[]) 我尝试以不同的方式操作我的字符串命令,看看它是否会成功。

我在 StackOverflow 上查看过类似的问题,但没有人遇到我正在经历的问题

public void startService(int serviceId, String serviceName, String 
ipAddress) {
    CMDExecutor executor = new CMDExecutor();
    try {
        String command = "cmd /C echo "+ password +" runas /user:"+ 
username +" "+ "\""+
                System.lineSeparator() +" sc\\\\"  +ipAddress+ " start "+ 
serviceName + "\"";
        String result = executor.getCMDResult(command);
        logger.info(result);
}

public class CMDExecutor {
public String getCMDResult(String command) throws IOException {
    Process cmdOutput;
    cmdOutput = Runtime.getRuntime().exec(command);
    StringWriter writer = new StringWriter();
    IOUtils.copy(cmdOutput.getInputStream(), writer, "UTF-8");
    return writer.toString();
 }
}

我期待下面的

SERVICE_NAME: serviceName
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 34916
        FLAGS              :

我正在返回部分命令,但没有任何变化,服务没有启动。

【问题讨论】:

  • 您的命令行格式错误:echo 有效地杀死了之后的所有内容,如果它试图将密码传递给 runas - 您不能这样做。 sc 后面有一个空格,换行无效。
  • 在调试模式下,当我复制命令的值时,我得到以下内容并将其粘贴到 CMD 上运行良好,这意味着它没有格式错误。我确实觉得奇怪的是,它需要在“sc”处换一个新行才能成功运行,因此我将它添加到我的命令中。 cmd /C 回显密码 runas /user:domainName\user " sc \\ipAddress start serviceName"
  • 来自 java.lang.Runtime 类的 javadoc:ProcessBuilder.start() 现在是使用修改后的环境启动进程的首选方法。
  • @Abra 我从mkyong.com/java/how-to-execute-shell-command-from-java 尝试过,但还是一样。
  • ProcessBuilderRuntime 不能替代 Windows 命令提示符。在我的 Windows 10 机器上,sc 是一个可执行文件:C:\Windows\System32\sc.exe。所以你应该使用new ProcessBuilder("sc.exe", ipAddress, "start", serviceName) 记住启动一个单独的线程来读取命令输出和另一个单独的线程来读取命令错误。如果需要将输入传递给命令,可以使用方法getOutputStream()

标签: java cmd


【解决方案1】:

在挣扎了几个小时后,简单的解决方案是将命令分成两部分,凭据部分和 sc 命令部分,如下所示。现在它按预期工作了。

PS。我选择从命令中删除 echo 以避免在日志文件中打印凭据。

public void startService(int serviceId, String serviceName, String 
ipAddress) {
CMDExecutor executor = new CMDExecutor();
try {
String credentialsCommand = "cmd /C echo "+ password +" runas /user:"+ username;
String startServiceCommand = "sc\\\\"  +ipAddress+ " start "+ serviceName";
String credentialsResult = executor.getCMDResult(credentialsCommand );
logger.info(credentialsResult );
String startServiceResult= executor.getCMDResult(startServiceCommand );
logger.info(startServiceResult);
}

【讨论】:

    猜你喜欢
    • 2012-12-07
    • 2017-10-04
    • 2021-07-22
    • 2012-10-07
    • 1970-01-01
    • 2021-07-18
    • 2020-01-16
    • 2014-12-28
    • 2014-09-16
    相关资源
    最近更新 更多