[英]Converting C# Application that runs CMD commands to one that runs Powershell commands with administrative privileges
I have a Visual studio Application that runs a series of Cmd commands using the following function 我有一个Visual Studio应用程序,它使用以下功能运行一系列Cmd命令
public static void AdminEx(string command) //Runs an Administrative Windows Command
{
var proc = new System.Diagnostics.ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = @"C:\Windows\System32";
proc.FileName = @"C:\Windows\System32\cmd.exe";
proc.Verb = "runas";
proc.Arguments = "/c " + command;
proc.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
var p = System.Diagnostics.Process.Start(proc);
p.WaitForExit();
}
We recently updated our Code and converted to Powershell. 我们最近更新了代码,并转换为Powershell。 How would I go about changing this function to accommodate for the new code.
我将如何更改此功能以适应新代码。 Is this still the most efficient way to go???
这仍然是最有效的方法吗???
Just change the line: 只需更改行:
proc.FileName = @"C:\Windows\System32\cmd.exe";
To: 至:
proc.FileName = @"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe";
This will make your software open powershell.exe instead of cmd.exe, I can't tell if that is the best way to go about this but I tried here and it worked for me. 这将使您的软件打开powershell.exe而不是cmd.exe,我无法确定这是否是解决此问题的最佳方法,但是我在这里尝试了一下,并且对我有用。
Otávio Caldonazo's helpful answer provides an effective solution, but it's worth explaining a few things: 奥塔维奥·卡尔多纳佐(OtávioCaldonazo)的有用答案提供了有效的解决方案,但值得解释以下几点:
Unless there are security concerns (someone having placed a nonstandard, malicious cmd.exe
/ powershell.exe
executable in a folder listed in the %PATH%
/ $env:PATH
environment variable that preempts the standard executables), it is simpler to use the executable file name alone, ie, just cmd.exe
/ powershell.exe
- this also avoids problems with non-standard Windows installations whose root is not C:\\Windows
. 除非有安全方面的考虑(有人将非标准的恶意
cmd.exe
/ powershell.exe
可执行文件放在%PATH%
/ $env:PATH
环境变量中列出的文件夹中,这些文件优先于标准可执行文件),否则使用仅可执行文件名 ,即cmd.exe
/ powershell.exe
这还避免了根不是 C:\\Windows
的非标准Windows安装的问题。
.FileName
, the .WorkingDirectory
property is effectively ignored with .Verb
set to runas
, because .WorkingDirectory
then doesn't actually set the working directory , but specifies where to find the executable , if specified by name only - however, lookups in %PATH%
/ $env:PATH
are still performed. .FileName
,该.WorkingDirectory
财产与忽略 .Verb
设置为runas
,因为.WorkingDirectory
那么实际上并没有设置工作目录 ,而是指定在哪里查找可执行文件 ,如果仅按名称指定-但是,仍会执行%PATH%
/ $env:PATH
中的查找。 While the /c
parameter to pass a command to the shell invoked happens to work with PowerShell's CLI too, PowerShell generally use sigil -
to prefix parameter names ; 虽然
/c
参数传递一个命令来调用的外壳会发生使用PowerShell的命令行工作过,PowerShell的一般使用印记-
以前缀参数名称 ; thus, 从而,
-c
(short for -Command
) is the better choice. -c
( -Command
)是更好的选择。
$PROFILE
initialization file by default (even when invoked with -Command
or -File
, even though that is generally undesirable), it's best to use -NoProfile -Command ...
instead. $PROFILE
默认初始化文件(即使与调用-Command
或-File
,尽管这通常是不希望), 最好使用-NoProfile -Command ...
代替。 Generally - if you don't need elevation (running as an admin ) - as an alternative to the - slow - creation of a child process via powershell.exe
, consider use of the PowerShell SDK (API) , which enables faster in-process execution while also enabling more fine-grained capturing of output streams (which you don't seem to be interested in in your particular scenario; while System.Diagnostics.ProcessStartInfo
allows you to capture stdout and stderr output via the .RedirectStandardOutput
and .RedirectStandardError
properties, note that PowerShell has additional output streams ). 一般 -如果你不需要 海拔 (运行作为管理员 ) -作为替代-慢-通过创建子进程的
powershell.exe
,考虑使用的PowerShell的SDK(API) ,实现了更高的进程执行,同时还可以实现更细粒度的输出流捕获 (您似乎对特定场景不感兴趣;而System.Diagnostics.ProcessStartInfo
允许您通过.RedirectStandardOutput
和.RedirectStandardError
属性捕获stdout和stderr输出,请注意,PowerShell具有其他输出流 )。
Based on the above, I suggest doing the following: 基于以上内容,我建议您执行以下操作:
var proc = new System.Diagnostics.ProcessStartInfo();
proc.UseShellExecute = true;
proc.Verb = "runas";
proc.FileName = @"powershell.exe";
proc.Arguments = "-NoProfile -Command " + command;
proc.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
var p = System.Diagnostics.Process.Start(proc);
p.WaitForExit();
Or, more concisely: 或者,更简洁地说:
using System;
using System.Diagnostics;
var proc = new ProcessStartInfo()
{
UseShellExecute = true,
Verb = "runas",
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "powershell.exe",
Arguments = "-NoProfile -Command " + command
};
Process.Start(proc).WaitForExit();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.