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 下载
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public 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);
获取所有的进程的命令行可以使用这个代码
复制代码
1
2
3
4foreach (var process in Process.GetProcesses()) { Console.WriteLine($"{process.ProcessName} {GetCommandLineOfProcess(process)}"); }
代码请看 https://github.com/lindexi/lindexi_gd/tree/cf4054b0f479986bd295a8e5b69c31ad8fd7fe10/GetProcessCommandLine
上面的代码需要引用一个 C++ 的库,看起来不清真,下面通过全部 C# 的代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130public 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; } }
获取所有进程的参数
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13[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 获取指定进程的输入命令行
最后
以上就是如意世界最近收集整理的关于2019-8-31-dotnet-获取指定进程的输入命令行的全部内容,更多相关2019-8-31-dotnet-获取指定进程内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复