内容简介:本文告诉大家如何在 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)}"); }
上面的代码需要引用一个 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)}"); } }
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- C# 获取进程退出代码
- 认识 JavaAgent:获取目标进程已加载的所有类
- .NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用?
- .NET/C# 获取一个正在运行的进程的命令行参数
- 荐 python脚本如何监听终止进程行为,如何通过脚本名获取pid
- 进程:进程生命周期
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JSP & Servlet学习笔记
【台湾】林信良 / 清华大学出版社 / 2012-5 / 58.00元
本书是作者多年来教学实践经验的总结,汇集了教学过程中学生在学习JSP & Servlet时遇到的概念、操作、应用或认证考试等问题及解决方案。 本书针对Servlet 3.0的新功能全面改版,无论是章节架构与范例程序代码,都做了全面更新。书中详细介绍了Servlet/ JSP与Web容器之间的关系,必要时从Tomcat源代码分析,了解Servlet/ JSP如何与容器互动。本书还涵盖了文本处理......一起来看看 《JSP & Servlet学习笔记》 这本书的介绍吧!