C# 执行PowerShell脚本的问题
本帖最后由 miocaro507 于 2022-12-13 13:46 编辑以下是一段C#执行PowerShell脚本的代码,其作用是结束远程计算机上的某个进程。但是这样运行之后,最后会输出以下错误:
Errors - Get-WmiObject : Invalid query "select * from Win32_Process where name = LabelPrinting.exe"
At line:1 char:14
+ ... Processes = Get-WmiObject -Class Win32_Process -ComputerName DSK0550...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) , ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
如果把变量script的值拷贝出来,贴到PowerShell的窗口去执行,则可以正常执行。请教是不是因为双引号造成的?怎么解决?谢谢
StringBuilder script = new StringBuilder();
script.AppendLine(string.Format("$Processes = Get-WmiObject -Class Win32_Process -ComputerName {0} -Filter 'name = \"{1}\"';", "DSK0550", "LabelPrinting.exe"));
script.AppendLine("foreach ($process in $processes) {");
script.AppendLine("$returnval = $process.terminate()");
script.AppendLine("if($returnval.returnvalue -eq 0) {");
script.AppendLine("write-host \"Closed\"");
script.AppendLine("} else {");
script.AppendLine("write-host \"Failed\"");
script.AppendLine("}");
script.AppendLine("}");
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = @"powershell.exe";
processInfo.Arguments = script.ToString();
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
processInfo.UseShellExecute = false;
processInfo.CreateNoWindow = true;
//start powershell process using process start info
Process process = new Process();
process.StartInfo = processInfo;
process.Start();
process.WaitForExit();
Console.WriteLine("Errors - {0}", process.StandardError.ReadToEnd()); 本帖最后由 MIAIONE 于 2022-12-13 13:58 编辑
可不可以考虑用内部WMI实现? 毕竟底层都是WMI服务
https://learn.microsoft.com/zh-cn/windows/win32/wmisdk/connecting-to-wmi-remotely-with-c- 进程名称用单引号试试? jackyyue_cn 发表于 2022-12-13 14:05
进程名称用单引号试试?
试了,不行,因为name前边已经有单引号了 using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace Subversion.GUI
{
class DosCommandOutput
{
/// <summary>
/// 执行DOS命令,返回DOS命令的输出
/// </summary>
/// <param name="dosCommand">dos命令</param>
/// <returns>返回输出,如果发生异常,返回空字符串</returns>
public static string Execute(string dosCommand)
{
return Execute(dosCommand, 60 * 10000);
}
/// <summary>
/// 执行DOS命令,返回DOS命令的输出
/// </summary>
/// <param name="dosCommand">dos命令</param>
/// <param name="milliseconds">等待命令执行的时间(单位:毫秒),如果设定为0,则无限等待</param>
/// <returns>返回输出,如果发生异常,返回空字符串</returns>
public static string Execute(string dosCommand, int milliseconds)
{
string output = ""; //输出字符串
if (!string.IsNullOrEmpty(dosCommand))
{
Process process = new Process(); //创建进程对象
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe"; //设定需要执行的命令
startInfo.Arguments = "/C " + dosCommand; //设定参数,其中的“/C”表示执行完命令后马上退出
startInfo.UseShellExecute = false; //不使用系统外壳程序启动
startInfo.RedirectStandardInput = false; //不重定向输入
startInfo.RedirectStandardOutput = true; //重定向输出
startInfo.CreateNoWindow = true; //不创建窗口
process.StartInfo = startInfo;
try
{
if (process.Start()) //开始进程
{
if (milliseconds == 0)
process.WaitForExit(); //这里无限等待进程结束
else
process.WaitForExit(milliseconds);//这里等待进程结束,等待时间为指定的毫秒
output = process.StandardOutput.ReadToEnd();//读取进程的输出
}
}
catch
{
}
finally
{
if (process != null)
process.Close();
}
}
return output;
}
public static string ExecuteEx(string dosCommand)
{
return ExecuteEx(dosCommand, 60 * 10000);
}
public static string ExecuteEx(string dosCommand, int milliseconds)
{
string output = ""; //输出字符串
if (!string.IsNullOrEmpty(dosCommand))
{
Process process = new Process(); //创建进程对象
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe"; //设定需要执行的命令
startInfo.Arguments = "/C " + dosCommand; //设定参数,其中的“/C”表示执行完命令后马上退出
startInfo.UseShellExecute = false; //不使用系统外壳程序启动
startInfo.RedirectStandardInput = false; //不重定向输入
//startInfo.RedirectStandardOutput = true; //重定向输出
startInfo.CreateNoWindow = true; //不创建窗口
process.StartInfo = startInfo;
try
{
if (process.Start()) //开始进程
{
if (milliseconds == 0)
process.WaitForExit(); //这里无限等待进程结束
else
process.WaitForExit(milliseconds);//这里等待进程结束,等待时间为指定的毫秒
output = process.StandardOutput.ReadToEnd();//读取进程的输出
}
}
catch
{
}
finally
{
if (process != null)
process.Close();
}
}
return output;
}
}
}
本帖最后由 apull 于 2022-12-13 20:42 编辑
可以把执行内容写到ps1文件里,用-Filet.ps1的参数执行。
StringBuilder script = new StringBuilder();
script.AppendLine(string.Format("$Processes = Get-WmiObject -Class Win32_Process -ComputerName {0} -Filter 'name = \"{1}\"';", "DSK0550", "LabelPrinting.exe"));
script.AppendLine("foreach ($process in $Processes) {");
script.AppendLine("$returnval = $process.terminate()");
script.AppendLine("if($returnval.returnvalue -eq 0) {");
script.AppendLine("write-host \"Closed\"");
script.AppendLine("} else {");
script.AppendLine("write-host \"Failed\"");
script.AppendLine("}");
script.AppendLine("}");
string file = Path.GetTempPath() + "t.ps1";
using (StreamWriter sw = new StreamWriter(file))
{
sw.Write(script.ToString());
}
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = @"powershell.exe";
//processInfo.Arguments = script.ToString();
processInfo.Arguments = string.Format("-File {0}", file);
processInfo.RedirectStandardError = true;
processInfo.RedirectStandardOutput = true;
processInfo.UseShellExecute = false;
processInfo.CreateNoWindow = true;
//start powershell process using process start info
Process process = new Process();
process.StartInfo = processInfo;
process.Start();
process.WaitForExit();
Console.WriteLine("Errors - {0}", process.StandardError.ReadToEnd());
File.Delete(file);
apull 发表于 2022-12-13 20:38
可以把执行内容写到ps1文件里,用-Filet.ps1的参数执行。
StringBu ...
太感谢了,你的办法可行!但是需要以管理员打开PowerShell,执行以下脚本:
Set-ExecutionPolicy -scope CurrentUser Unrestricted
否则会报 t.ps1 cannot be loaded because running scripts is disabled on this system.
页:
[1]