You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Job.cs 4.6 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4. using Shadowsocks.Controller;
  5. namespace Shadowsocks.Util.ProcessManagement
  6. {
  7. /*
  8. * See:
  9. * http://stackoverflow.com/questions/6266820/working-example-of-createjobobject-setinformationjobobject-pinvoke-in-net
  10. */
  11. public class Job : IDisposable
  12. {
  13. [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
  14. static extern IntPtr CreateJobObject(IntPtr a, string lpName);
  15. [DllImport("kernel32.dll")]
  16. static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);
  17. [DllImport("kernel32.dll", SetLastError = true)]
  18. static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
  19. [DllImport("kernel32.dll", SetLastError = true)]
  20. [return: MarshalAs(UnmanagedType.Bool)]
  21. static extern bool CloseHandle(IntPtr hObject);
  22. private IntPtr handle;
  23. private bool disposed;
  24. public Job()
  25. {
  26. handle = CreateJobObject(IntPtr.Zero, null);
  27. var info = new JOBOBJECT_BASIC_LIMIT_INFORMATION
  28. {
  29. LimitFlags = 0x2000
  30. };
  31. var extendedInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION
  32. {
  33. BasicLimitInformation = info
  34. };
  35. int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
  36. IntPtr extendedInfoPtr = Marshal.AllocHGlobal(length);
  37. Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);
  38. if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr, (uint)length))
  39. throw new Exception(string.Format("Unable to set information. Error: {0}", Marshal.GetLastWin32Error()));
  40. }
  41. public void Dispose()
  42. {
  43. Dispose(true);
  44. GC.SuppressFinalize(this);
  45. }
  46. private void Dispose(bool disposing)
  47. {
  48. if (disposed)
  49. return;
  50. if (disposing) { }
  51. Close();
  52. disposed = true;
  53. }
  54. public void Close()
  55. {
  56. CloseHandle(handle);
  57. handle = IntPtr.Zero;
  58. }
  59. public bool AddProcess(IntPtr processHandle)
  60. {
  61. var succ = AssignProcessToJobObject(handle, processHandle);
  62. if (!succ)
  63. {
  64. var err = Marshal.GetLastWin32Error();
  65. Logging.Error("Failed to call AssignProcessToJobObject! GetLastError=" + err);
  66. }
  67. return succ;
  68. }
  69. public bool AddProcess(int processId)
  70. {
  71. return AddProcess(Process.GetProcessById(processId).Handle);
  72. }
  73. }
  74. #region Helper classes
  75. [StructLayout(LayoutKind.Sequential)]
  76. struct IO_COUNTERS
  77. {
  78. public UInt64 ReadOperationCount;
  79. public UInt64 WriteOperationCount;
  80. public UInt64 OtherOperationCount;
  81. public UInt64 ReadTransferCount;
  82. public UInt64 WriteTransferCount;
  83. public UInt64 OtherTransferCount;
  84. }
  85. [StructLayout(LayoutKind.Sequential)]
  86. struct JOBOBJECT_BASIC_LIMIT_INFORMATION
  87. {
  88. public Int64 PerProcessUserTimeLimit;
  89. public Int64 PerJobUserTimeLimit;
  90. public UInt32 LimitFlags;
  91. public UIntPtr MinimumWorkingSetSize;
  92. public UIntPtr MaximumWorkingSetSize;
  93. public UInt32 ActiveProcessLimit;
  94. public UIntPtr Affinity;
  95. public UInt32 PriorityClass;
  96. public UInt32 SchedulingClass;
  97. }
  98. [StructLayout(LayoutKind.Sequential)]
  99. public struct SECURITY_ATTRIBUTES
  100. {
  101. public UInt32 nLength;
  102. public IntPtr lpSecurityDescriptor;
  103. public Int32 bInheritHandle;
  104. }
  105. [StructLayout(LayoutKind.Sequential)]
  106. struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
  107. {
  108. public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
  109. public IO_COUNTERS IoInfo;
  110. public UIntPtr ProcessMemoryLimit;
  111. public UIntPtr JobMemoryLimit;
  112. public UIntPtr PeakProcessMemoryUsed;
  113. public UIntPtr PeakJobMemoryUsed;
  114. }
  115. public enum JobObjectInfoType
  116. {
  117. AssociateCompletionPortInformation = 7,
  118. BasicLimitInformation = 2,
  119. BasicUIRestrictions = 4,
  120. EndOfJobTimeInformation = 6,
  121. ExtendedLimitInformation = 9,
  122. SecurityLimitInformation = 5,
  123. GroupInformation = 11
  124. }
  125. #endregion
  126. }