Написать 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
Листинг программы
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
 
namespace JobKillProcess
{
    class Program
    {
        #region ~ Platform Invoke ~
 
        #region ~ Enums ~
 
        private enum JobObjectInfoClass
        {
            JobObjectExtendedLimitInformation = 9,
        }
 
        [Flags]
        private enum LimitFlags
        {
            JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = 0x00002000,
        }
 
        #endregion
 
        #region ~ Structures ~
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684147%28v=vs.85%29.aspx[/url]
        /// </summary>
        private struct JOBOBJECT_BASIC_LIMIT_INFORMATION
        {
            internal long PerProcessUserTimeLimit;
            internal long PerJobUserTimeLimit;
            internal LimitFlags LimitFlags;
            internal IntPtr MinimumWorkingSetSize;
            internal IntPtr MaximumWorkingSetSize;
            internal uint ActiveProcessLimit;
            internal UIntPtr Affinity;
            internal uint PriorityClass;
            internal uint SchedulingClass;
        }
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684125%28v=vs.85%29.aspx[/url]
        /// </summary>
        private struct IO_COUNTERS
        {
            internal ulong ReadOperationCount;
            internal ulong WriteOperationCount;
            internal ulong OtherOperationCount;
            internal ulong ReadTransferCount;
            internal ulong WriteTransferCount;
            internal ulong OtherTransferCount;
        }
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms684156%28v=vs.85%29.aspx[/url]
        /// </summary>
        private struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION
        {
            internal JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
            internal IO_COUNTERS IoInfo;
            internal IntPtr ProcessMemoryLimit;
            internal IntPtr JobMemoryLimit;
            internal IntPtr PeakProcessMemoryUsed;
            internal IntPtr PeakJobMemoryUsed;
        }
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms686331%28v=vs.85%29.aspx[/url]
        /// </summary>
        private struct STARTUPINFO
        {
            internal int cb;
            internal IntPtr lpReserved; // Используем IntPtr взамен string, чтобы избежать ненужного преобразования данных
            internal IntPtr lpDesktop;  // Используем IntPtr взамен string, чтобы избежать ненужного преобразования данных
            internal IntPtr lpTitle;    // Используем IntPtr взамен string, чтобы избежать ненужного преобразования данных
            internal int dwX;
            internal int dwY;
            internal int dwXSize;
            internal int dwYSize;
            internal int dwXCountChars;
            internal int dwYCountChars;
            internal uint dwFillAttribute;
            internal uint dwFlags;
            internal ushort wShowWindow;
            internal ushort cbReserved2;
            internal IntPtr lpReserved2;
            internal IntPtr hStdInput;
            internal IntPtr hStdOutput;
            internal IntPtr hStdError;
        }
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms684873%28v=vs.85%29.aspx[/url]
        /// </summary>
        private struct PROCESS_INFORMATION
        {
            internal IntPtr hProcess;
            internal IntPtr hThread;
            internal int dwProcessId;
            internal int dwThreadId;
        }
 
        #endregion
 
        #region ~ Kernel32 functions ~
 
        private const string Kernel32Lib = "kernel32.dll";
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms682409%28v=vs.85%29.aspx[/url]
        /// </summary>
        /// <param name="lpJobAttributes"></param>
        /// <param name="lpName"></param>
        /// <returns></returns>
        [DllImport(Kernel32Lib, SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr CreateJobObject(
            IntPtr lpJobAttributes,
            string lpName
            );
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms681949%28v=vs.85%29.aspx[/url]
        /// </summary>
        /// <param name="hJob"></param>
        /// <param name="hProcess"></param>
        /// <returns></returns>
        [DllImport(Kernel32Lib, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool AssignProcessToJobObject(
            IntPtr hJob,
            IntPtr hProcess
            );
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms686216%28v=vs.85%29.aspx[/url]
        /// </summary>
        /// <param name="hJob"></param>
        /// <param name="JobObjectInfoClass"></param>
        /// <param name="lpJobObjectInfo"></param>
        /// <param name="cbJobObjectInfoLength"></param>
        /// <returns></returns>
        [DllImport(Kernel32Lib, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetInformationJobObject(
            IntPtr hJob,
            JobObjectInfoClass JobObjectInfoClass,
            // Используем ExtendedLimitInformation, т.к. того требует JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
            ref JOBOBJECT_EXTENDED_LIMIT_INFORMATION lpJobObjectInfo,
            int cbJobObjectInfoLength
            );
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx[/url]
        /// </summary>
        /// <param name="lpApplicationName"></param>
        /// <param name="lpCommandLine"></param>
        /// <param name="lpProcessAttributes"></param>
        /// <param name="lpThreadAttributes"></param>
        /// <param name="bInheritHandles"></param>
        /// <param name="dwCreationFlags"></param>
        /// <param name="lpEnvironment"></param>
        /// <param name="lpCurrentDirectory"></param>
        /// <param name="lpStartupInfo"></param>
        /// <param name="lpProcessInformation"></param>
        /// <returns></returns>
        [DllImport(Kernel32Lib, SetLastError = true, CharSet = CharSet.Unicode)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CreateProcess(
            string lpApplicationName,
            string lpCommandLine,
            IntPtr lpProcessAttributes,
            IntPtr lpThreadAttributes,
            [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles,
            uint dwCreationFlags,
            IntPtr lpEnvironment,
            string lpCurrentDirectory,
            ref STARTUPINFO lpStartupInfo,
            out PROCESS_INFORMATION lpProcessInformation
            );
 
        /// <summary>
        /// [url]https://msdn.microsoft.com/ru-ru/library/windows/desktop/ms724211%28v=vs.85%29.aspx[/url]
        /// </summary>
        /// <param name="hObject"></param>
        /// <returns></returns>
        [DllImport(Kernel32Lib, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(
            IntPtr hObject
            );
 
        #endregion
 
        #endregion
 
        static void Main()
        {
            // Флаг показывающий что процесс создан успешно
            var processCreated = false;
            var pi = default(PROCESS_INFORMATION);
            var hJob = IntPtr.Zero;
 
            try
            {
                // Создаём процесс калькулятора
                var si = new STARTUPINFO();
                // cb - обязательное поле, отвечает за размер передаваемой структуры
                si.cb = Marshal.SizeOf(si);
 
                bool result = CreateProcess(
                    null, "calc.exe", IntPtr.Zero, IntPtr.Zero,
                    false, 0, IntPtr.Zero, null, ref si, out pi);
 
                if (!result)
                    // Ничего не передаём, исключение должно само корректно получить номер ошибки (Marshal.GetLastWin32Error)
                    throw new Win32Exception();
                processCreated = true;
 
                // Создаём безымянную работу с дефолтными настройками безопасности
                hJob = CreateJobObject(IntPtr.Zero, null);
 
                if (hJob == IntPtr.Zero)
                    throw new Win32Exception();
 
                // Задаём ограничения для работы
                var limitInfo = new JOBOBJECT_EXTENDED_LIMIT_INFORMATION();
                limitInfo.BasicLimitInformation.LimitFlags = LimitFlags.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
 
                result = SetInformationJobObject(
                    hJob, JobObjectInfoClass.JobObjectExtendedLimitInformation,
                    ref limitInfo, Marshal.SizeOf(limitInfo));
 
                if (!result)
                    throw new Win32Exception();
 
                // Привязываем процесс калькулятора к работе
                if (!AssignProcessToJobObject(hJob, pi.hProcess))
                    throw new Win32Exception();
 
                Console.WriteLine("Enter any key to exit...");
                Console.ReadKey();
            }
            catch (Win32Exception ex)
            {
                Console.WriteLine("Error: {0} (code: {1})", ex.Message, ex.ErrorCode);
                Console.ReadKey();
            }
            finally
            {
                // Закрываем предоставленные системой ресусры: дескрипторы потока и процесса
                if (processCreated)
                {
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);
                }
 
                // Завершаем работу корректно
                if (hJob != IntPtr.Zero)
                    CloseHandle(hJob);
            }
        }
    }
}

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


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

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

11   голосов , оценка 4.091 из 5
Похожие ответы