吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1142|回复: 6
收起左侧

[求助] C# 执行PowerShell脚本的问题

[复制链接]
miocaro507 发表于 2022-12-13 13:41
本帖最后由 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: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand


如果把变量script的值拷贝出来,贴到PowerShell的窗口去执行,则可以正常执行。请教是不是因为双引号造成的?怎么解决?谢谢

[C#] 纯文本查看 复制代码
            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:56
本帖最后由 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
 楼主| miocaro507 发表于 2022-12-13 15:07
jackyyue_cn 发表于 2022-12-13 14:05
进程名称用单引号试试?

试了,不行,因为name前边已经有单引号了
coolcalf 发表于 2022-12-13 16:09
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:38
本帖最后由 apull 于 2022-12-13 20:42 编辑

可以把执行内容写到ps1文件里,用-File  t.ps1的参数执行。
[C#] 纯文本查看 复制代码
        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); 
 楼主| miocaro507 发表于 2022-12-14 13:36
apull 发表于 2022-12-13 20:38
可以把执行内容写到ps1文件里,用-File  t.ps1的参数执行。
[mw_shl_code=csharp,true]
        StringBu ...

太感谢了,你的办法可行!但是需要以管理员打开PowerShell,执行以下脚本:

Set-ExecutionPolicy -scope CurrentUser Unrestricted

否则会报 t.ps1 cannot be loaded because running scripts is disabled on this system.
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 01:35

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表