Runtime(运行时)

  1 /// <summary>运行时</summary>
  2     public static class Runtime
  3     {
  4         #region 控制台
  5         static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
  6  
  7         private static Boolean? _IsConsole;
  8         /// <summary>是否控制台。用于判断是否可以执行一些控制台操作。</summary>
  9         public static Boolean IsConsole
 10         {
 11             get
 12             {
 13                 if (_IsConsole != null) return _IsConsole.Value;
 14  
 15                 IntPtr ip = Win32Native.GetStdHandle(-11);
 16                 if (ip == IntPtr.Zero || ip == INVALID_HANDLE_VALUE)
 17                     _IsConsole = false;
 18                 else
 19                 {
 20                     ip = Win32Native.GetStdHandle(-10);
 21                     if (ip == IntPtr.Zero || ip == INVALID_HANDLE_VALUE)
 22                         _IsConsole = false;
 23                     else
 24                         _IsConsole = true;
 25                 }
 26  
 27                 return _IsConsole.Value;
 28             }
 29         }
 30  
 31         private static IntPtr _consoleOutputHandle;
 32         private static IntPtr ConsoleOutputHandle
 33         {
 34             [SecurityCritical]
 35             get
 36             {
 37                 if (_consoleOutputHandle == IntPtr.Zero) _consoleOutputHandle = Win32Native.GetStdHandle(-11);
 38                 return _consoleOutputHandle;
 39             }
 40         }
 41  
 42         /// <summary>获取PE文件类型。扩展方法</summary>
 43         /// <param name="e"></param>
 44         /// <returns></returns>
 45         public static PEFileKinds GetPEFileKinds(this MemberInfo e)
 46         {
 47             return GetPEFileKinds(Path.GetFullPath(e.Module.Assembly.Location));
 48  
 49         }
 50  
 51         /// <summary>Parses the PE header and determines whether the given assembly is a console application.</summary>
 52         /// <param name="assemblyPath">The path of the assembly to check.</param>
 53         /// <remarks>The magic numbers in this method are extracted from the PE/COFF file
 54         /// format specification available from http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx
 55         /// </remarks>
 56         static PEFileKinds GetPEFileKinds(string assemblyPath)
 57         {
 58             using (var s = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read))
 59             {
 60                 return GetPEFileKinds(s);
 61             }
 62         }
 63  
 64         private static PEFileKinds GetPEFileKinds(Stream s)
 65         {
 66             var rawPeSignatureOffset = new byte[4];
 67             s.Seek(0x3c, SeekOrigin.Begin);
 68             s.Read(rawPeSignatureOffset, 0, 4);
 69             int peSignatureOffset = rawPeSignatureOffset[0];
 70             peSignatureOffset |= rawPeSignatureOffset[1] << 8;
 71             peSignatureOffset |= rawPeSignatureOffset[2] << 16;
 72             peSignatureOffset |= rawPeSignatureOffset[3] << 24;
 73             var coffHeader = new byte[24];
 74             s.Seek(peSignatureOffset, SeekOrigin.Begin);
 75             s.Read(coffHeader, 0, 24);
 76             byte[] signature = { (byte)'P', (byte)'E', (byte)'\0', (byte)'\0' };
 77             for (int index = 0; index < 4; index++)
 78             {
 79                 if (coffHeader[index] != signature[index]) throw new InvalidOperationException("Attempted to check a non PE file for the console subsystem!");
 80             }
 81             var subsystemBytes = new byte[2];
 82             s.Seek(68, SeekOrigin.Current);
 83             s.Read(subsystemBytes, 0, 2);
 84             int subSystem = subsystemBytes[0] | subsystemBytes[1] << 8;
 85             return
 86                 // http://support.microsoft.com/kb/90493
 87                 subSystem == 3 ? PEFileKinds.ConsoleApplication :
 88                 subSystem == 2 ? PEFileKinds.WindowApplication :
 89                 PEFileKinds.Dll; /*IMAGE_SUBSYSTEM_WINDOWS_CUI*/
 90         }
 91         #endregion
 92  
 93         #region Web环境
 94         /// <summary>是否Web环境</summary>
 95         public static Boolean IsWeb { get { return !String.IsNullOrEmpty(HttpRuntime.AppDomainAppId); } }
 96         #endregion
 97  
 98         #region 64位系统
 99         /// <summary>确定当前操作系统是否为 64 位操作系统。</summary>
100         /// <returns>如果操作系统为 64 位操作系统,则为 true;否则为 false。</returns>
101         public static Boolean Is64BitOperatingSystem
102         {
103             [SecuritySafeCritical]
104             get
105             {
106                 if (Is64BitProcess) return true;
107  
108                 Boolean flag;
109                 return Win32Native.DoesWin32MethodExist("kernel32.dll", "IsWow64Process") && Win32Native.IsWow64Process(Win32Native.GetCurrentProcess(), out flag) && flag;
110             }
111         }
112  
113         /// <summary>确定当前进程是否为 64 位进程。</summary>
114         /// <returns>如果进程为 64 位进程,则为 true;否则为 false。</returns>
115         public static bool Is64BitProcess { get { return IntPtr.Size == 8; } }
116         #endregion
117  
118         #region 内存设置
119         /// <summary>设置进程的程序集大小,将部分物理内存占用转移到虚拟内存</summary>
120         /// <param name="pid">要设置的进程ID</param>
121         /// <param name="min">最小值</param>
122         /// <param name="max">最大值</param>
123         /// <returns></returns>
124         public static Boolean SetProcessWorkingSetSize(Int32 pid, Int32 min, Int32 max)
125         {
126             Process p = pid <= 0 ? Process.GetCurrentProcess() : Process.GetProcessById(pid);
127             return Win32Native.SetProcessWorkingSetSize(p.Handle, min, max);
128         }
129  
130         /// <summary>释放当前进程所占用的内存</summary>
131         /// <returns></returns>
132         public static Boolean ReleaseMemory()
133         {
134             GC.Collect();
135  
136             return SetProcessWorkingSetSize(0, -1, -1);
137         }
138         #endregion
139     }
140  
141     class Win32Native
142     {
143         [DllImport("kernel32.dll", SetLastError = true)]
144         internal static extern IntPtr GetStdHandle(int nStdHandle);
145  
146         [SecurityCritical]
147         internal static bool DoesWin32MethodExist(string moduleName, string methodName)
148         {
149             IntPtr moduleHandle = GetModuleHandle(moduleName);
150             if (moduleHandle == IntPtr.Zero) return false;
151             return GetProcAddress(moduleHandle, methodName) != IntPtr.Zero;
152         }
153  
154         [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
155         private static extern IntPtr GetModuleHandle(string moduleName);
156  
157         [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
158         private static extern IntPtr GetProcAddress(IntPtr hModule, string methodName);
159  
160         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
161         internal static extern IntPtr GetCurrentProcess();
162  
163         [return: MarshalAs(UnmanagedType.Bool)]
164         [DllImport("kernel32.dll", SetLastError = true)]
165         internal static extern bool IsWow64Process([In] IntPtr hSourceProcessHandle, [MarshalAs(UnmanagedType.Bool)] out bool isWow64);
166  
167         [DllImport("kernel32.dll")]
168         internal static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
169     }
View Code

 

posted @ 2017-03-22 16:32  AAABONE  阅读(142)  评论(0编辑  收藏  举报