如何在运行命令时以管理员身份运行cmd?

8

这是我的代码:

try
{
    ProcessStartInfo procStartInfo = new ProcessStartInfo(
                                            "cmd.exe", 
                                            "/c " + command);
    procStartInfo.UseShellExecute = true;
    procStartInfo.CreateNoWindow = true;
    procStartInfo.Verb = "runas";
    procStartInfo.Arguments = "/env /user:" + "Administrator" + " cmd" + command;

    ///command contains the command to be executed in cmd
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = procStartInfo;
    proc.Start();
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message);
}

I want to keep

procStartInfo.UseShellExecute = true 
procStartInfo.RedirectStandardInput = false;

在不使用process.standardinput的情况下执行命令是否可能?我试图执行传入参数的命令,但命令没有执行。


有没有可能在不使用Process.StandardInput的情况下执行命令?我尝试执行传递给参数的命令,但命令没有执行。您目前没有使用它,所以这个问题并没有太多意义。请为用户着想,允许命令提示符可见,这样他们就知道发生了什么。 - Security Hound
1
你不需要 Verb。那并不是你想象中的意思。我想。 - Roger Lipscombe
@Ramhound procStartInfo.Arguments = "/env /user:" + "Administrator" + " cmd" + command;procStartInfo.Arguments = "/env /user:" + "管理员" + " cmd" + 命令; - purvang
@mtijn 是的,它在那个时候失败了。我想知道是否有其他方式可以给出命令。 - purvang
这可能会有所帮助:在C#中以管理员权限启动进程 - DK.
2个回答

6

正如@mtijn所说,您有很多正在覆盖的内容。您还需要确保正确转义内容。

假设您想以提升权限的方式运行以下命令:

dir c:\

首先,如果您只是通过Process.Start()运行此命令,窗口会弹出并立即关闭,因为没有任何东西可以保持窗口打开。它处理命令并退出。为了保持窗口打开,我们可以将命令包装在单独的命令窗口中,并使用/K开关来保持其运行:

cmd /K "dir c:\"

为了以管理员身份运行该命令,我们可以使用runas.exe,但需要对内容进行更多的转义。根据帮助文档(runas /?),传递给runas的命令中任何带引号的部分都需要用反斜杠进行转义。不幸的是,对上述命令执行此操作会得到双反斜杠,这会让cmd解析器感到困惑,因此还需要对其进行转义。因此,上述命令最终变为:
cmd /K \"dir c:\\\"

最后,使用您提供的语法,我们可以将所有内容包装成一个runas命令,并在进一步的引号中包含上面的命令:
runas /env /user:Administrator "cmd /K \"dir c:\\\""

请从命令提示符中运行上述命令,以确保其按预期工作。

考虑到这一切,最终的代码变得更容易组装:

        //Assuming that we want to run the following command:
        //dir c:\

        //The command that we want to run
        string subCommand = @"dir";

        //The arguments to the command that we want to run
        string subCommandArgs = @"c:\";

        //I am wrapping everything in a CMD /K command so that I can see the output and so that it stays up after executing
        //Note: arguments in the sub command need to have their backslashes escaped which is taken care of below
        string subCommandFinal = @"cmd /K \""" + subCommand.Replace(@"\", @"\\") + " " + subCommandArgs.Replace(@"\", @"\\") + @"\""";

        //Run the runas command directly
        ProcessStartInfo procStartInfo = new ProcessStartInfo("runas.exe");
        procStartInfo.UseShellExecute = true;
        procStartInfo.CreateNoWindow = true;

        //Create our arguments
        string finalArgs = @"/env /user:Administrator """ + subCommandFinal + @"""";
        procStartInfo.Arguments = finalArgs;

        //command contains the command to be executed in cmd
        using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
        {
            proc.StartInfo = procStartInfo;
            proc.Start();
        }

我运行了你在 cmd 中建议的以下命令:runas /env /user:Administrator "cmd /K "dir c:\"" 尽管我输入了密码,它仍然要求密码并且失败了,输出如下:无法运行 cmd /k "dir c:"。 - purvang
你运行了 runas /env /user:Administrator "cmd /K \"dir c:\\\"" 还是 cmd runas /env /user:Administrator "cmd /K \"dir c:\\\""?第一个是你应该运行的。 - Chris Haas
我将其运行为 runas /env /user:Administrator "cmd /K "dir c:\"",但是它给出以下错误:无法运行 cmd /k "dir c:"。 - purvang
如果你遇到了 RUNAS ERROR: Unable to run - cmd /K "dir c:\" 的错误,那么你也应该会得到一个主要的错误,例如 1326: Logon failure: unknown user name or bad password.,是吗? - Chris Haas
1
如果错误代码是 1326,那么它是由于用户名或密码错误,你需要解决这个问题。问题不在命令上,而在凭据方面。如果你处于域环境中,你可能需要将 "Administrator" 改为 "YOURDOMAIN\Administrator"。如果你遇到错误代码 1327,则表示有某种组策略正在阻止它。 - Chris Haas
显示剩余2条评论

1

为什么你要用参数初始化进程对象,然后在稍后覆盖这些参数?另外,当你设置参数时,你将“command”连接到“cmd”,这没有太多意义,可能是导致失败的地方(看起来你缺少了一个空格)。

此外,你目前正在使用标准命令行,你可能想要考虑使用runas工具。你也可以从命令行调用runas。

还有,为什么你要从命令行运行“command”?为什么不直接从Process.Start开始并提供管理员权限呢?以下是一些伪代码:

Process p = Process.Start(new ProcessStartInfo()
{
    FileName = <your executable>,
    Arguments = <any arguments>,
    UserName = "Administrator",
    Password = <password>,
    UseShellExecute = false,
    WorkingDirectory = <directory of your executable>
});

谢谢您的建议,但我不知道如何在Process.Start期间授予管理员权限。您能否提供一些示例代码或示例? - purvang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接