Написать DEMO программу для работы с CreateJobObject/ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE - C#

Узнай цену своей работы

Формулировка задачи:

Нужно написать программу, которая демонстрирует работу CreateJobObject/ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE . И программа должна запускать калькулятор,если убить процесс нашей программы (с диспетчера например), то дочерный процесс тоже должен закрыватся. пс. пример должен быть простым и понятным, чтобы такие как я, не мучались.. в этой теме Пример работы с JobObject тоже пытались сделать, что то подобное, но у меня c этим примером не закрывается калькулятор. И с этими примерами, тоже ничего не получается у меня: https://searchcode.com/codesearch/view/28089595/ https://code.google.com/p/managed-lz...Process.cs?r=3 http://stackoverflow.com/questions/6...pinvoke-in-net Не кидать камнями.. Спасибо!

Решение задачи: «Написать DEMO программу для работы с CreateJobObject/ JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE»

textual
Листинг программы
  1. using System;
  2. using System.ComponentModel;
  3. using System.Diagnostics;
  4. using System.Runtime.InteropServices;
  5.  
  6. namespace JobKillProcess
  7. {
  8.     class Program
  9.     {
  10.         #region ~ Platform Invoke ~
  11.  
  12.         #region ~ Enums ~
  13.  
  14.         private enum JobObjectInfoClass
  15.         {
  16.             JobObjectExtendedLimitInformation = 9,
  17.         }
  18.  
  19.         [Flags]
  20.         private enum LimitFlags
  21.         {
  22.             JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000,
  23.         }
  24.  
  25.         #endregion
  26.  
  27.         #region ~ Structures ~
  28.  
  29.         /// <summary>
  30.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684147%28v=vs.85%29.aspx[/url]
  31.         /// </summary>
  32.         private struct JOBOBJECT_BASIC_LIMIT_INFORMATION
  33.         {
  34.             internal long PerProcessUserTimeLimit;
  35.             internal long PerJobUserTimeLimit;
  36.             internal LimitFlags LimitFlags;
  37.             internal IntPtr MinimumWorkingSetSize;
  38.             internal IntPtr MaximumWorkingSetSize;
  39.             internal uint ActiveProcessLimit;
  40.             internal UIntPtr Affinity;
  41.             internal uint PriorityClass;
  42.             internal uint SchedulingClass;
  43.         }
  44.  
  45.         /// <summary>
  46.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684125%28v=vs.85%29.aspx[/url]
  47.         /// </summary>
  48.         private struct IO_COUNTERS
  49.         {
  50.             internal ulong ReadOperationCount;
  51.             internal ulong WriteOperationCount;
  52.             internal ulong OtherOperationCount;
  53.             internal ulong ReadTransferCount;
  54.             internal ulong WriteTransferCount;
  55.             internal ulong OtherTransferCount;
  56.         }
  57.  
  58.         /// <summary>
  59.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684156%28v=vs.85%29.aspx[/url]
  60.         /// </summary>
  61.         private struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
  62.         {
  63.             internal JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
  64.             internal IO_COUNTERS IoInfo;
  65.             internal IntPtr ProcessMemoryLimit;
  66.             internal IntPtr JobMemoryLimit;
  67.             internal IntPtr PeakProcessMemoryUsed;
  68.             internal IntPtr PeakJobMemoryUsed;
  69.         }
  70.  
  71.         /// <summary>
  72.         /// [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx[/url]
  73.         /// </summary>
  74.         private struct STARTUPINFO
  75.         {
  76.             internal int cb;
  77.             internal IntPtr lpReserved; // Используем IntPtr взамен string, чтобы избежать ненужного преобразования данных
  78.             internal IntPtr lpDesktop;  // Используем IntPtr взамен string, чтобы избежать ненужного преобразования данных
  79.             internal IntPtr lpTitle;    // Используем IntPtr взамен string, чтобы избежать ненужного преобразования данных
  80.             internal int dwX;
  81.             internal int dwY;
  82.             internal int dwXSize;
  83.             internal int dwYSize;
  84.             internal int dwXCountChars;
  85.             internal int dwYCountChars;
  86.             internal uint dwFillAttribute;
  87.             internal uint dwFlags;
  88.             internal ushort wShowWindow;
  89.             internal ushort cbReserved2;
  90.             internal IntPtr lpReserved2;
  91.             internal IntPtr hStdInput;
  92.             internal IntPtr hStdOutput;
  93.             internal IntPtr hStdError;
  94.         }
  95.  
  96.         /// <summary>
  97.         /// [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873%28v=vs.85%29.aspx[/url]
  98.         /// </summary>
  99.         private struct PROCESS_INFORMATION
  100.         {
  101.             internal IntPtr hProcess;
  102.             internal IntPtr hThread;
  103.             internal int dwProcessId;
  104.             internal int dwThreadId;
  105.         }
  106.  
  107.         #endregion
  108.  
  109.         #region ~ Kernel32 functions ~
  110.  
  111.         private const string Kernel32Lib = "kernel32.dll";
  112.  
  113.         /// <summary>
  114.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682409%28v=vs.85%29.aspx[/url]
  115.         /// </summary>
  116.         /// <param name="lpJobAttributes"></param>
  117.         /// <param name="lpName"></param>
  118.         /// <returns></returns>
  119.         [DllImport(Kernel32Lib, SetLastError = true, CharSet = CharSet.Unicode)]
  120.         private static extern IntPtr CreateJobObject(
  121.             IntPtr lpJobAttributes,
  122.             string lpName
  123.             );
  124.  
  125.         /// <summary>
  126.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms681949%28v=vs.85%29.aspx[/url]
  127.         /// </summary>
  128.         /// <param name="hJob"></param>
  129.         /// <param name="hProcess"></param>
  130.         /// <returns></returns>
  131.         [DllImport(Kernel32Lib, SetLastError = true)]
  132.         [return: MarshalAs(UnmanagedType.Bool)]
  133.         private static extern bool AssignProcessToJobObject(
  134.             IntPtr hJob,
  135.             IntPtr hProcess
  136.             );
  137.  
  138.         /// <summary>
  139.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686216%28v=vs.85%29.aspx[/url]
  140.         /// </summary>
  141.         /// <param name="hJob"></param>
  142.         /// <param name="JobObjectInfoClass"></param>
  143.         /// <param name="lpJobObjectInfo"></param>
  144.         /// <param name="cbJobObjectInfoLength"></param>
  145.         /// <returns></returns>
  146.         [DllImport(Kernel32Lib, SetLastError = true)]
  147.         [return: MarshalAs(UnmanagedType.Bool)]
  148.         private static extern bool SetInformationJobObject(
  149.             IntPtr hJob,
  150.             JobObjectInfoClass JobObjectInfoClass,
  151.             // Используем ExtendedLimitInformation, т.к. того требует JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
  152.             ref JOBOBJECT_EXTENDED_LIMIT_INFORMATION lpJobObjectInfo,
  153.             int cbJobObjectInfoLength
  154.             );
  155.  
  156.         /// <summary>
  157.         /// [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx[/url]
  158.         /// </summary>
  159.         /// <param name="lpApplicationName"></param>
  160.         /// <param name="lpCommandLine"></param>
  161.         /// <param name="lpProcessAttributes"></param>
  162.         /// <param name="lpThreadAttributes"></param>
  163.         /// <param name="bInheritHandles"></param>
  164.         /// <param name="dwCreationFlags"></param>
  165.         /// <param name="lpEnvironment"></param>
  166.         /// <param name="lpCurrentDirectory"></param>
  167.         /// <param name="lpStartupInfo"></param>
  168.         /// <param name="lpProcessInformation"></param>
  169.         /// <returns></returns>
  170.         [DllImport(Kernel32Lib, SetLastError = true, CharSet = CharSet.Unicode)]
  171.         [return: MarshalAs(UnmanagedType.Bool)]
  172.         private static extern bool CreateProcess(
  173.             string lpApplicationName,
  174.             string lpCommandLine,
  175.             IntPtr lpProcessAttributes,
  176.             IntPtr lpThreadAttributes,
  177.             [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles,
  178.             uint dwCreationFlags,
  179.             IntPtr lpEnvironment,
  180.             string lpCurrentDirectory,
  181.             ref STARTUPINFO lpStartupInfo,
  182.             out PROCESS_INFORMATION lpProcessInformation
  183.             );
  184.  
  185.         /// <summary>
  186.         /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms724211%28v=vs.85%29.aspx[/url]
  187.         /// </summary>
  188.         /// <param name="hObject"></param>
  189.         /// <returns></returns>
  190.         [DllImport(Kernel32Lib, SetLastError = true)]
  191.         [return: MarshalAs(UnmanagedType.Bool)]
  192.         private static extern bool CloseHandle(
  193.             IntPtr hObject
  194.             );
  195.  
  196.         #endregion
  197.  
  198.         #endregion
  199.  
  200.         static void Main()
  201.         {
  202.             // Флаг показывающий что процесс создан успешно
  203.             var processCreated = false;
  204.             var pi = default(PROCESS_INFORMATION);
  205.             var hJob = IntPtr.Zero;
  206.  
  207.             try
  208.             {
  209.                 // Создаём процесс калькулятора
  210.                 var si = new STARTUPINFO();
  211.                 // cb - обязательное поле, отвечает за размер передаваемой структуры
  212.                 si.cb = Marshal.SizeOf(si);
  213.  
  214.                 bool result = CreateProcess(
  215.                     null, "calc.exe", IntPtr.Zero, IntPtr.Zero,
  216.                     false, 0, IntPtr.Zero, null, ref si, out pi);
  217.  
  218.                 if (!result)
  219.                     // Ничего не передаём, исключение должно само корректно получить номер ошибки (Marshal.GetLastWin32Error)
  220.                     throw new Win32Exception();
  221.                 processCreated = true;
  222.  
  223.                 // Создаём безымянную работу с дефолтными настройками безопасности
  224.                 hJob = CreateJobObject(IntPtr.Zero, null);
  225.  
  226.                 if (hJob == IntPtr.Zero)
  227.                     throw new Win32Exception();
  228.  
  229.                 // Задаём ограничения для работы
  230.                 var limitInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
  231.                 limitInfo.BasicLimitInformation.LimitFlags = LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
  232.  
  233.                 result = SetInformationJobObject(
  234.                     hJob, JobObjectInfoClass.JobObjectExtendedLimitInformation,
  235.                     ref limitInfo, Marshal.SizeOf(limitInfo));
  236.  
  237.                 if (!result)
  238.                     throw new Win32Exception();
  239.  
  240.                 // Привязываем процесс калькулятора к работе
  241.                 if (!AssignProcessToJobObject(hJob, pi.hProcess))
  242.                     throw new Win32Exception();
  243.  
  244.                 Console.WriteLine("Enter any key to exit...");
  245.                 Console.ReadKey();
  246.             }
  247.             catch (Win32Exception ex)
  248.             {
  249.                 Console.WriteLine("Error: {0} (code: {1})", ex.Message, ex.ErrorCode);
  250.                 Console.ReadKey();
  251.             }
  252.             finally
  253.             {
  254.                 // Закрываем предоставленные системой ресусры: дескрипторы потока и процесса
  255.                 if (processCreated)
  256.                 {
  257.                     CloseHandle(pi.hThread);
  258.                     CloseHandle(pi.hProcess);
  259.                 }
  260.  
  261.                 // Завершаем работу корректно
  262.                 if (hJob != IntPtr.Zero)
  263.                     CloseHandle(hJob);
  264.             }
  265.         }
  266.     }
  267. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 4.091 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы