/// <summary>
        /// Overridden ProcessRecord.
        /// </summary>
        protected override void ProcessRecord()
        {
            if (ParameterSetName == "ForScriptBlock")
            {
                if (Thread.ProcessId != NtProcess.Current.ProcessId)
                {
                    throw new ArgumentException("Must specify thread in current process to use script block.");
                }

                ApcCallback callback = (a, b, c) => PSUtils.InvokeWithArg(ScriptBlock, a, b, c);
                if (Special)
                {
                    Thread.QueueSpecialUserApc(callback, new IntPtr(Argument1), new IntPtr(Argument2), new IntPtr(Argument3));
                }
                else
                {
                    Thread.QueueUserApc(callback, new IntPtr(Argument1), new IntPtr(Argument2), new IntPtr(Argument3));
                }
            }
            else
            {
                if (Special)
                {
                    Thread.QueueSpecialUserApc(new IntPtr(ApcRoutine), new IntPtr(Argument1), new IntPtr(Argument2), new IntPtr(Argument3));
                }
                else
                {
                    Thread.QueueUserApc(new IntPtr(ApcRoutine), new IntPtr(Argument1), new IntPtr(Argument2), new IntPtr(Argument3));
                }
            }
        }
 /// <summary>
 /// Queue a user APC to the thread.
 /// </summary>
 /// <param name="apc_routine">The APC callback delegate.</param>
 /// <param name="normal_context">Context parameter.</param>
 /// <param name="system_argument1">System argument 1.</param>
 /// <param name="system_argument2">System argument 2.</param>
 /// <remarks>This is only for APCs in the current process. You also must ensure the delegate is
 /// valid at all times as this method doesn't take a reference to the delegate to prevent it being
 /// garbage collected.</remarks>
 public void QueueUserApc(ApcCallback apc_routine, IntPtr normal_context, IntPtr system_argument1, IntPtr system_argument2)
 {
     NtSystemCalls.NtQueueApcThread(Handle, Marshal.GetFunctionPointerForDelegate(apc_routine),
                                    normal_context, system_argument1, system_argument2).ToNtException();
 }
 /// <summary>
 /// Queue a user APC to the thread.
 /// </summary>
 /// <param name="apc_routine">The APC callback delegate.</param>
 /// <param name="normal_context">Context parameter.</param>
 /// <param name="system_argument1">System argument 1.</param>
 /// <param name="system_argument2">System argument 2.</param>
 /// <remarks>This is only for APCs in the current process. You also must ensure the delegate is
 /// valid at all times as this method doesn't take a reference to the delegate to prevent it being
 /// garbage collected.</remarks>
 public void QueueUserApc(ApcCallback apc_routine, IntPtr normal_context, IntPtr system_argument1, IntPtr system_argument2)
 {
     QueueUserApc(apc_routine, normal_context, system_argument1, system_argument2);
 }
 /// <summary>
 /// Queue a user APC to the thread.
 /// </summary>
 /// <param name="apc_routine">The APC callback delegate.</param>
 /// <param name="normal_context">Context parameter.</param>
 /// <param name="system_argument1">System argument 1.</param>
 /// <param name="system_argument2">System argument 2.</param>
 /// <param name="throw_on_error">True to throw on error.</param>
 /// <returns>The NT status code.</returns>
 /// <remarks>This is only for APCs in the current process. You also must ensure the delegate is
 /// valid at all times as this method doesn't take a reference to the delegate to prevent it being
 /// garbage collected.</remarks>
 public NtStatus QueueUserApc(ApcCallback apc_routine, IntPtr normal_context,
                              IntPtr system_argument1, IntPtr system_argument2, bool throw_on_error)
 {
     return(QueueUserApc(Marshal.GetFunctionPointerForDelegate(apc_routine),
                         normal_context, system_argument1, system_argument2, throw_on_error));
 }