dotnet 获取指定进程的输入命令行

栏目: ASP.NET · 发布时间: 5年前

内容简介:本文告诉大家如何在 dotnet 获取指定的进程的命令行参数很多的程序在启动的时候都需要传入参数,那么如何拿到这些程序传入的参数?我找到两个方法,一个需要引用 C++ 库支持 x86 和 x64 程序,另一个都是C#代码,但是只支持 x64 程序

本文告诉大家如何在 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)}");
            }
        }

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTTP Essentials

HTTP Essentials

Stephen A. Thomas、Stephen Thomas / Wiley / 2001-03-08 / USD 34.99

The first complete reference guide to the essential Web protocol As applications and services converge and Web technologies not only assume HTTP but require developers to manipulate it, it is be......一起来看看 《HTTP Essentials》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具