Как автоматически рассчитывать / обновлять дату выполнения в таблице обслуживания

Существует еще один подходящий метод, простой и эффективный, для завершения дочерних процессов при завершении программы. Вы можете реализовать и приложить отладчик к ним от родителя; когда заканчивается родительский процесс, дочерние процессы будут убиты ОС. Он может пойти в обоих направлениях с отладчиком от родителя от дочернего элемента (обратите внимание, что вы можете прикреплять только один отладчик одновременно). Здесь вы можете найти дополнительную информацию по этому вопросу . .

Здесь у вас есть класс утилиты, который запускает новый процесс и присоединяет к нему отладчик. Он был адаптирован из этого поста Роджером Кнаппом. Единственное требование состоит в том, что оба процесса должны иметь одинаковую битту. Вы не можете отлаживать 32-битный процесс из 64-битного процесса или наоборот.

public class ProcessRunner
{
    #region "API imports"

    private const int DBG_CONTINUE = 0x00010002;
    private const int DBG_EXCEPTION_NOT_HANDLED = unchecked((int) 0x80010001);

    private enum DebugEventType : int
    {
        CREATE_PROCESS_DEBUG_EVENT = 3,
        //Reports a create-process debugging event. The value of u.CreateProcessInfo specifies a CREATE_PROCESS_DEBUG_INFO structure.
        CREATE_THREAD_DEBUG_EVENT = 2,
        //Reports a create-thread debugging event. The value of u.CreateThread specifies a CREATE_THREAD_DEBUG_INFO structure.
        EXCEPTION_DEBUG_EVENT = 1,
        //Reports an exception debugging event. The value of u.Exception specifies an EXCEPTION_DEBUG_INFO structure.
        EXIT_PROCESS_DEBUG_EVENT = 5,
        //Reports an exit-process debugging event. The value of u.ExitProcess specifies an EXIT_PROCESS_DEBUG_INFO structure.
        EXIT_THREAD_DEBUG_EVENT = 4,
        //Reports an exit-thread debugging event. The value of u.ExitThread specifies an EXIT_THREAD_DEBUG_INFO structure.
        LOAD_DLL_DEBUG_EVENT = 6,
        //Reports a load-dynamic-link-library (DLL) debugging event. The value of u.LoadDll specifies a LOAD_DLL_DEBUG_INFO structure.
        OUTPUT_DEBUG_STRING_EVENT = 8,
        //Reports an output-debugging-string debugging event. The value of u.DebugString specifies an OUTPUT_DEBUG_STRING_INFO structure.
        RIP_EVENT = 9,
        //Reports a RIP-debugging event (system debugging error). The value of u.RipInfo specifies a RIP_INFO structure.
        UNLOAD_DLL_DEBUG_EVENT = 7,
        //Reports an unload-DLL debugging event. The value of u.UnloadDll specifies an UNLOAD_DLL_DEBUG_INFO structure.
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct DEBUG_EVENT
    {
        [MarshalAs(UnmanagedType.I4)] public DebugEventType dwDebugEventCode;
        public int dwProcessId;
        public int dwThreadId;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] public byte[] bytes;
    }

    [DllImport("Kernel32.dll", SetLastError = true)]
    private static extern bool DebugActiveProcess(int dwProcessId);

    [DllImport("Kernel32.dll", SetLastError = true)]
    private static extern bool WaitForDebugEvent([Out] out DEBUG_EVENT lpDebugEvent, int dwMilliseconds);

    [DllImport("Kernel32.dll", SetLastError = true)]
    private static extern bool ContinueDebugEvent(int dwProcessId, int dwThreadId, int dwContinueStatus);

    [DllImport("Kernel32.dll", SetLastError = true)]
    public static extern bool IsDebuggerPresent();

    #endregion

    public Process ChildProcess { get; set; }

    public bool StartProcess(string fileName)
    {
        var processStartInfo = new ProcessStartInfo(fileName)
        {
            UseShellExecute = false,
            WindowStyle = ProcessWindowStyle.Normal,
            ErrorDialog = false
        };

        this.ChildProcess = Process.Start(processStartInfo);
        if (ChildProcess == null)
            return false;

        new Thread(NullDebugger) {IsBackground = true}.Start(ChildProcess.Id);
        return true;
    }

    private void NullDebugger(object arg)
    {
        // Attach to the process we provided the thread as an argument
        if (DebugActiveProcess((int) arg))
        {
            var debugEvent = new DEBUG_EVENT {bytes = new byte[1024]};
            while (!this.ChildProcess.HasExited)
            {
                if (WaitForDebugEvent(out debugEvent, 1000))
                {
                    // return DBG_CONTINUE for all events but the exception type
                    var continueFlag = DBG_CONTINUE;
                    if (debugEvent.dwDebugEventCode == DebugEventType.EXCEPTION_DEBUG_EVENT)
                        continueFlag = DBG_EXCEPTION_NOT_HANDLED;
                    ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, continueFlag);
                }
            }
        }
        else
        {
            //we were not able to attach the debugger
            //do the processes have the same bitness?
            //throw ApplicationException("Unable to attach debugger") // Kill child? // Send Event? // Ignore?
        }
    }
}

Использование:

    new ProcessRunner().StartProcess("c:\\Windows\\system32\\calc.exe");

0
задан Alex Crim 13 July 2018 в 15:17
поделиться

1 ответ

Если вы используете SQL Server , вы можете создать повторяющееся задание , которое обновляет столбец NextDueDate. Или найти что-то подобное в вашей соответствующей базе данных SQL. В противном случае вы можете создать простую службу на C #, которая делает то же самое.

Мне интересно, хотя было бы лучше иметь две таблицы, одну для Contracts и одну для Bills с отношением от 1 до многих. Поэтому, если контракт был создан в течение 1 года с 12 месячными платежами, вы должны генерировать строки 1 Contract и 12 Bill и иметь булевский столбец с именем IsPaid для таблицы Bills. Таким образом, у вас есть прослеживаемость для каждого ожидаемого обслуживания или счета.

Затем у вас может быть представление, в котором есть столбцы с данными Contract, и вычисленный столбец NextDueDate, который получает расчет соответствующих счетов, упорядоченных по дате, самая низкая, чем текущая дата.

1
ответ дан Matthew Steven Monkan 17 August 2018 в 12:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: