加拿大华人论坛 美国华人新闻.NET Framework Process FAQ
在加拿大
.NET Framework Process FAQAuthor: Gang Peng, Kit GeorgeUpdated: October 2003Applies: .NET Framework V1.0 and V1.1, and WhidbeyFrequently asked questions about System.Diagnostics.Process class. .NET Framework Process FAQ 1Why does Process class have a dependency on performance counter? 1How do I get the process name quickly? 2How do I use Process class under non-admin account? 2Why do I get weird exceptions with DateTime class on the callstack? 2Why can’t I get the start up information from Process.StartInfo? 3How I can know the parent process ID of a process? 3Why do I can get weird exception messages like “this operation is not supported on remote machines” when trying to get process names on a remote machine? 3In moving to 64bit, how will properties on Process, which may exceed an Int’s max range, be affected? 4Why does Process class have a dependency on performance counter?Process class exposes performance information about processes. In order to get performance information about remote processes, we need to query performance information on remote machine. We used the same code to get performance information about processes on local machine in Everett. That’s why Process class has dependency on performance counter. However, this approach has several problems: (1) Performance information is not available to non-admin account which is not in performance counter users group on windows server 2003. So process class could not get process performance information in this case(2) Getting performance data from all the processes on the machine is pretty expensive. OS might load lots of DLLs and it might take seconds to complete. The light of floppy drive will be on when OS tries to find the index for some performance counter(3) If the performance counter data was corrupted for any reason, Process class could throw an exception while trying to convert some raw performance information into DateTime(4) Process class could not be used to get process information on machines without process performance counter. Performance counters can be disabled on Windows. See following link for details: http://www.microsoft.com/windows2000/techinfo/reskit/en-us/default.asp?url=/windows2000/techinfo/reskit/en-us/regentry/94214.aspThe good news is that we have changed the implementation of Process class in Whidbey (our next release). Process class doesn’t have a dependency on performance counter information any more (this is only true for local processes).How do I get the process name quickly?If you want to get Process.ProcessName, there is an alternative:Process.MainModule.ModuleName. How do I use Process class under non-admin account?From Windows Server 2003, you will get an exception if you try to get process performance information under a non-admin account. The workaround is to add that account into performance counter users group.Why do I get weird exceptions with DateTime class on the callstack?Some customers have seen exceptions with following callstack on some particular machines:System.InvalidOperationException: Couldn't get process information from remote machine. ---> System.ArgumentOutOfRangeException: Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.Parameter name: ticks at System.DateTime..ctor(Int64 ticks) at System.DateTime.Subtract(TimeSpan value) at System.Diagnostics.NtProcessManager.GetThreadInfo(PERF_OBJECT_TYPE type, IntPtr instancePtr, PERF_COUNTER_DEFINITION[] counters) at System.Diagnostics.NtProcessManager.GetProcessInfos(PerformanceCounterLib library, Int32 processIndex, Int32 threadIndex, IntPtr dataBlockPtr) at System.Diagnostics.NtProcessManager.GetProcessInfos(PerformanceCounterLib library) --- End of inner exception stack trace --- at System.Diagnostics.NtProcessManager.GetProcessInfos(PerformanceCounterLib library) at System.Diagnostics.NtProcessManager.GetProcessInfos(String machineName, Boolean isRemoteMachine) at System.Diagnostics.ProcessManager.GetProcessInfos(String machineName) at System.Diagnostics.Process.GetProcesses(String machineName) at System.Diagnostics.Process.GetProcesses() at Process_Reader.Module1.Main()This happens because the performance information from some process is corrupted and we couldn’t convert the information into DateTime. We did drill to the bottom of one instance and the problem was related to a particular setting in the Adaptec SCSI Bios. When the customer reset the to 'factory default settings' on both chains of the SCSI bios it fixed the problem. However, this might not be true in all the cases, so it might not work for you. We use Win32 API to get process and thread time information in Whidbey, so you will not see this exception in future.Why can’t I get the start up information from Process.StartInfo?We only use StartInfo to start a process, so if a process is not created by using Process class. StartInfo class will be empty. Then you may wonder how you can get the command line information. There are a few solutions:(1) If you want to get the command line information for current process, use Environment.CommandLine(2) System.WMI Win32_Process has a field “CommandLine”. Please refer to MSDN document for details about this class.(3) There are some techniques which depend on the layout of OS process structure. It is not guaranteed to work on all the platforms, so use it at your own risk. Check following MSDN articles: http://msdn.microsoft.com/msdnmag/issues/02/06/debug/default.aspxHow I can know the parent process ID of a process?If you have looked at process performance counter information, you probably have seen something called “Creating Process Id”. We didn’t expose this piece of information in Process class (we will probably add it in future.) You can use following code to get the creating process id:using System.Diagnostics;using System;class ProcessInformation { public static void Main() { PerformanceCounter pc = new PerformanceCounter("Process", "Creating Process Id", "windbg"); Process p = Process.GetProcessById((int)pc.RawValue); if(p.MainModule.ModuleName.Equals("svchost.exe")) { Console.WriteLine("Created by scheduler"); } else { Console.WriteLine("Created without schedule."); } }}Why do I can get weird exception messages like “this operation is not supported on remote machines” when trying to get process names on a remote machine?You should always be able to get process names on a remote machine if you access right to performance information on that machine. We do something special in get_ProcessName: we try to complete the process name if they are truncated by OS. We try to get the module information for a process name which 15 fifteen characters. This operation is not supported on remote machine and we shouldn’t try to do that for remote processes. Following is a workaround for this problem: try{Console.WriteLine(myProcesses[x].ProcessName);} catch(NotSupportedException ){Type processType = typeof(Process); FieldInfo info = processType.GetField("processInfo", BindingFlags.NonPublic| BindingFlags.IgnoreCase| BindingFlags.Instance);Object obj = info.GetValue( myProcesses[x]); Type processInfoType = obj.GetType(); FieldInfo info2 = processInfoType.GetField("processName", BindingFlags.NonPublic| BindingFlags.IgnoreCase| BindingFlags.Instance|BindingFlags.Public); string name = (string)info2.GetValue( obj); Console.WriteLine( name); }Above code uses internal knowledge about process which is not documented. This works on RTM and Everett, but we do not guarantee this will work in feature. Of course, this bug will be fixed in our next release.In moving to 64bit, how will properties on Process, which may exceed an Int’s max range, be affected?There are a number of APIs on Process, which reflect the size of memory, and return an Int32. These have worked perfectly well, but it is not uncommon on a 64bit machine, for the amount of memory to exceed the maximum value for an Int32. In these situations, the existing APIs are not suitable.We cannot simply remove the Int32 APIs and introduce new 64bit versions, because of compatibility requirements (calls bind to this API interface based on it returning an int, and returning a long will break existing callers). For this reason, the existing Int32 APIs are becoming obsolete, and new versions of the APIs are being introduced, which return 64 bit values.The APIs being made obsolete will be:NonpagedSystemMemorySize PagedMemorySizePagedSystemMemorySizePeakPagedMemorySizePeakVirtualMemorySizePeakWorkingSetPrivateMemorySizeVirtualMemorySizeWorkingSet
·中文新闻 2024年巴西G20峰会:直言不讳的前外交官山上真吾指责总理安东尼
·中文新闻 在内皮恩河寻找失踪男子