• 2019-8-31-dotnet-获取指定进程的输入命令行


    title author date CreateTime categories
    dotnet 获取指定进程的输入命令行
    lindexi
    2019-08-31 16:55:58 +0800
    2019-02-22 11:25:47 +0800
    dotnet

    本文告诉大家如何在 dotnet 获取指定的进程的命令行参数

    很多的程序在启动的时候都需要传入参数,那么如何拿到这些程序传入的参数?

    我找到两个方法,一个需要引用 C++ 库支持 x86 和 x64 程序,另一个都是C#代码,但是只支持 x64 程序

    本文提供一个由 StackOverflow 大神开发的库拿到进程的命令行

    在使用下面的代码需要引用两个 C++ 的库,可以从 csdn 下载

    使用下面的代码就可以拿到传入进程的参数,在使用之前,需要在输出的文件夹里面包含 ProcCmdLine32.dll 和 ProcCmdLine64.dll 可以从csdn 下载

            public static string GetCommandLineOfProcess(Process process)
            {
                // max size of a command line is USHORT/sizeof(WCHAR), so we are going
                // just allocate max USHORT for sanity sake.
                var stringBuilder = new StringBuilder(0xFFFF);
                if (Environment.Is64BitProcess)
                {
                    GetProcCmdLine64((uint) process.Id, stringBuilder, (uint) stringBuilder.Capacity);
                }
                else
                {
                    GetProcCmdLine32((uint) process.Id, stringBuilder, (uint) stringBuilder.Capacity);
                }
    
                return stringBuilder.ToString();
            }
    
            [DllImport("ProcCmdLine32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetProcCmdLine")]
            private static extern bool GetProcCmdLine32(uint nProcId, StringBuilder stringBuilder, uint dwSizeBuf);
    
            [DllImport("ProcCmdLine64.dll", CharSet = CharSet.Unicode, EntryPoint = "GetProcCmdLine")]
            private static extern bool GetProcCmdLine64(uint nProcId, StringBuilder stringBuilder, uint dwSizeBuf);

    获取所有的进程的命令行可以使用这个代码

                foreach (var process in Process.GetProcesses())
                {
                    Console.WriteLine($"{process.ProcessName} {GetCommandLineOfProcess(process)}");
                }

    代码请看 https://github.com/lindexi/lindexi_gd/tree/cf4054b0f479986bd295a8e5b69c31ad8fd7fe10/GetProcessCommandLine

    上面的代码需要引用一个 C++ 的库,看起来不清真,下面通过全部 C# 的代码

            public static string GetCommandLineOfProcess(int processId)
            {
                var pid = processId;
    
                var pbi = new NativeMethods.PROCESS_BASIC_INFORMATION();
    
                IntPtr proc = NativeMethods.OpenProcess
                (
                    PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid
                );
    
                if (proc == IntPtr.Zero)
                {
                    return "";
                }
    
                if (NativeMethods.NtQueryInformationProcess(proc, 0, ref pbi, pbi.Size, IntPtr.Zero) == 0)
                {
                    var buff = new byte[IntPtr.Size];
                    if (NativeMethods.ReadProcessMemory
                    (
                        proc,
                        (IntPtr) (pbi.PebBaseAddress.ToInt32() + 0x10),
                        buff,
                        IntPtr.Size, out _
                    ))
                    {
                        var buffPtr = BitConverter.ToInt32(buff, 0);
                        var commandLine = new byte[Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING))];
    
                        if
                        (
                            NativeMethods.ReadProcessMemory
                            (
                                proc, (IntPtr) (buffPtr + 0x40),
                                commandLine,
                                Marshal.SizeOf(typeof(NativeMethods.UNICODE_STRING)), out _
                            )
                        )
                        {
                            var ucsData = ByteArrayToStructure<NativeMethods.UNICODE_STRING>(commandLine);
                            var parms = new byte[ucsData.Length];
                            if
                            (
                                NativeMethods.ReadProcessMemory
                                (
                                    proc, ucsData.buffer, parms,
                                    ucsData.Length, out _
                                )
                            )
                            {
                                return Encoding.Unicode.GetString(parms);
                            }
                        }
                    }
                }
    
                NativeMethods.CloseHandle(proc);
    
                return "";
            }
    
            private const uint PROCESS_QUERY_INFORMATION = 0x400;
            private const uint PROCESS_VM_READ = 0x010;
    
            private static T ByteArrayToStructure<T>(byte[] bytes) where T : struct
            {
                var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                var stuff = (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
                handle.Free();
                return stuff;
            }
    
            private static class NativeMethods
            {
                [DllImport("kernel32.dll", SetLastError = true)]
                [return: MarshalAs(UnmanagedType.Bool)]
                internal static extern bool CloseHandle(IntPtr hObject);
    
                [DllImport("kernel32.dll", SetLastError = true)]
                internal static extern IntPtr OpenProcess
                (
                    uint dwDesiredAccess,
                    [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
                    int dwProcessId
                );
    
    
                [DllImport("kernel32.dll", SetLastError = true)]
                [return: MarshalAs(UnmanagedType.Bool)]
                internal static extern bool ReadProcessMemory
                (
                    IntPtr hProcess,
                    IntPtr lpBaseAddress,
                    byte[] lpBuffer,
                    int nSize,
                    out IntPtr lpNumberOfBytesRead
                );
    
                [DllImport("ntdll.dll")]
                internal static extern int NtQueryInformationProcess
                (
                    IntPtr ProcessHandle,
                    uint ProcessInformationClass,
                    ref PROCESS_BASIC_INFORMATION ProcessInformation,
                    uint ProcessInformationLength,
                    IntPtr ReturnLength
                );
    
                [StructLayout(LayoutKind.Sequential, Pack = 1)]
                internal struct PROCESS_BASIC_INFORMATION
                {
                    internal int ExitProcess;
                    internal IntPtr PebBaseAddress;
                    internal IntPtr AffinityMask;
                    internal int BasePriority;
                    internal IntPtr UniqueProcessId;
                    internal IntPtr InheritedFromUniqueProcessId;
    
                    internal uint Size => (uint) Marshal.SizeOf(typeof(PROCESS_BASIC_INFORMATION));
                }
    
                [StructLayout(LayoutKind.Sequential, Pack = 1)]
                internal struct UNICODE_STRING
                {
                    internal ushort Length;
                    internal ushort MaximumLength;
                    internal IntPtr buffer;
                }
            }

    获取所有进程的参数

            [STAThread]
            private static void Main(string[] args)
            {
                if (Environment.Is64BitProcess)
                {
                    throw new InvalidOperationException("暂时只支持x86程序");
                }
    
                foreach (var process in Process.GetProcesses())
                {
                    Console.WriteLine($"{process.ProcessName} {GetCommandLineOfProcess(process.Id)}");
                }
            }

    更简单是通过 WMI 获取指定进程的输入命令行

  • 相关阅读:
    设计模式(8)[JS版]-JavaScript设计模式之如何实现适配器模式???
    JS+CSS实现左右文字滚动
    设计模式(7)[JS版]-JavaScript设计模式之原型模式如何实现???
    如何更聪明地学习:20种让你更高效学习的科学方法
    设计模式(6)[JS版]-JavaScript如何实现抽象工厂模式?
    设计模式(5)[JS版]-JavaScript如何实现工厂方法模式?
    设计模式(4)[JS版]-JavaScript如何实现建造者模式?
    设计模式(3)[JS版]-JavaScript中的构造函数模式是什么?
    PAT A1094 The Largest Generation (25分)
    PAT A1090 Highest Price in Supply Chain (25分)(边界问题)
  • 原文地址:https://www.cnblogs.com/lindexi/p/12085805.html
Copyright © 2020-2023  润新知