Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 计划时Messagebox在服务器上不工作_C#_Winforms - Fatal编程技术网

C# 计划时Messagebox在服务器上不工作

C# 计划时Messagebox在服务器上不工作,c#,winforms,C#,Winforms,我有以下Windows窗体程序。它有一个自动关闭的消息框 我已在Windows Server 2008 R2上使用“无论用户是否登录都运行”。但是,当我注销时,这样的计划不起作用。但是,当直接执行exe或通过批处理文件执行exe时,它工作正常。问题出在消息框上 我应该做什么代码更改/设置更改才能使其与调度程序一起工作 注意:在我的真实场景中,我需要一个自动关闭的messagebox。虽然在这里似乎没有必要 参考资料 代码 public partial class Form1 : F

我有以下
Windows窗体
程序。它有一个自动关闭的消息框

我已在
Windows Server 2008 R2
上使用
“无论用户是否登录都运行”
。但是,当我注销时,这样的计划不起作用。但是,当直接执行exe或通过批处理文件执行exe时,它工作正常。问题出在消息框上

我应该做什么代码更改/设置更改才能使其与调度程序一起工作

注意:在我的真实场景中,我需要一个自动关闭的messagebox。虽然在这里似乎没有必要

参考资料

  • 代码

    public partial class Form1 : Form
    {
        int logNumber = 0;
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            WriteLogFunction("**");
            while (true)
            {
                WriteLogFunction("**");
                AutoClosingMessageBox.Show("A", "B", 1000);
                WriteLogFunction(">>");
            }
    
        }
    
        private void WriteLogFunction(string strMessage)
        {
            string fileName = "MYLog_" + DateTime.Now.ToString("yyyyMMMMdd");
            fileName = fileName + ".txt";
            using (StreamWriter w = File.AppendText(fileName))
            {
                w.WriteLine("\r\n{0} ..... {1} + {2}ms >>> {3}  ", logNumber.ToString(), DateTime.Now.ToLongTimeString(), DateTime.Now.Millisecond.ToString(), strMessage);
                logNumber++;
            }
        }
    }
    public class AutoClosingMessageBox
    {
        System.Threading.Timer _timeoutTimer;
        string _caption;
        AutoClosingMessageBox(string text, string caption, int timeout)
        {
            _caption = caption;
            _timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
                null, timeout, System.Threading.Timeout.Infinite);
            MessageBox.Show(text, caption);
        }
        public static void Show(string text, string caption, int timeout)
        {
            new AutoClosingMessageBox(text, caption, timeout);
        }
        void OnTimerElapsed(object state)
        {
            IntPtr mbWnd = FindWindow(null, _caption);
            if (mbWnd != IntPtr.Zero)
                SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            _timeoutTimer.Dispose();
        }
        const int WM_CLOSE = 0x0010;
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
    }
    

    这个问题可能没有解决办法。如果设置为运行“用户是否登录”的任务包含任何用户交互元素,则该任务将不会运行。它不会创建用户界面,没有窗口和窗口句柄,也没有基于窗口的消息泵


    如果应用程序绝对需要消息泵,那么它绝对需要用户界面。两者相辅相成。

    我使用消息泵实现了所需的功能(该消息框为我提供的功能)(尽管这不是首选方法)

    这主要基于以下两个方面:

    代码

    public partial class Form1 : Form
    {
        int logNumber = 0;
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            WriteLogFunction("**");
            while (true)
            {
                WriteLogFunction("**");
                AutoClosingMessageBox.Show("A", "B", 1000);
                WriteLogFunction(">>");
            }
    
        }
    
        private void WriteLogFunction(string strMessage)
        {
            string fileName = "MYLog_" + DateTime.Now.ToString("yyyyMMMMdd");
            fileName = fileName + ".txt";
            using (StreamWriter w = File.AppendText(fileName))
            {
                w.WriteLine("\r\n{0} ..... {1} + {2}ms >>> {3}  ", logNumber.ToString(), DateTime.Now.ToLongTimeString(), DateTime.Now.Millisecond.ToString(), strMessage);
                logNumber++;
            }
        }
    }
    public class AutoClosingMessageBox
    {
        System.Threading.Timer _timeoutTimer;
        string _caption;
        AutoClosingMessageBox(string text, string caption, int timeout)
        {
            _caption = caption;
            _timeoutTimer = new System.Threading.Timer(OnTimerElapsed,
                null, timeout, System.Threading.Timeout.Infinite);
            MessageBox.Show(text, caption);
        }
        public static void Show(string text, string caption, int timeout)
        {
            new AutoClosingMessageBox(text, caption, timeout);
        }
        void OnTimerElapsed(object state)
        {
            IntPtr mbWnd = FindWindow(null, _caption);
            if (mbWnd != IntPtr.Zero)
                SendMessage(mbWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            _timeoutTimer.Dispose();
        }
        const int WM_CLOSE = 0x0010;
        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
    }
    
    注意:在项目中添加对
    WindowsBase
    dll的引用

    public partial class Form1 : Form
    {
        int logNumber = 0;
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            WriteLogFunction("**");
    
            try
            {
                while (true)
                {
                    WriteLogFunction("**");
                    MessagePumpHelper.PumpMessage(1000);
                    WriteLogFunction(">>");
                }
            }
            catch (Exception ex)
            {
                WriteLogFunction(ex.Message);
                WriteLogFunction(ex.InnerException.ToString());
            }
    
    
        }
    
        private void WriteLogFunction(string strMessage)
        {
            string fileName = "MYLog_" + DateTime.Now.ToString("yyyyMMMMdd");
            fileName = fileName + ".txt";
            using (StreamWriter w = File.AppendText(fileName))
            {
                w.WriteLine("\r\n{0} ..... {1} + {2}ms >>> {3}  ", logNumber.ToString(), DateTime.Now.ToLongTimeString(), DateTime.Now.Millisecond.ToString(), strMessage);
                logNumber++;
            }
        }
    }
    
    #region WaitExt
    
    public static class MessagePumpHelper
    {
        public static void PumpMessage(int milliSecondsWait)
        {
            var dummy = new ManualResetEvent(false);
            WaitExt.WaitOneAndPump(dummy, milliSecondsWait);
        }
    }
    
    // WaitOneAndPump
    public static class WaitExt
    {
        public static bool WaitOneAndPump(this WaitHandle handle, int millisecondsTimeout)
        {
            using (var operationPendingMre = new ManualResetEvent(false))
            {
                var result = false;
                var startTick = Environment.TickCount;
    
                //using System.Windows.Threading; //From WindowsBase dll
                var dispatcher = Dispatcher.CurrentDispatcher;
                var frame = new DispatcherFrame();
    
                var handles = new[] { 
                        handle.SafeWaitHandle.DangerousGetHandle(), 
                        operationPendingMre.SafeWaitHandle.DangerousGetHandle() };
    
                // idle processing plumbing
                //using System.Windows.Threading; //From WindowsBase dll
                DispatcherOperation idleOperation = null;
                Action idleAction = () => { idleOperation = null; };
                Action enqueIdleOperation = () =>
                {
                    if (idleOperation != null)
                        idleOperation.Abort();
                    // post an empty operation to make sure that 
                    // onDispatcherInactive will be called again
                    idleOperation = dispatcher.BeginInvoke(
                        idleAction,
                        DispatcherPriority.ApplicationIdle);
                };
    
                // timeout plumbing
                Func<uint> getTimeout;
                if (Timeout.Infinite == millisecondsTimeout)
                    getTimeout = () => INFINITE;
                else
                    getTimeout = () => (uint)Math.Max(0, millisecondsTimeout + startTick - Environment.TickCount);
    
                //using System.Windows.Threading; //From WindowsBase dll
                DispatcherHookEventHandler onOperationPosted = (s, e) =>
                {
                    // this may occur on a random thread,
                    // trigger a helper event and 
                    // unblock MsgWaitForMultipleObjectsEx inside onDispatcherInactive
                    operationPendingMre.Set();
                };
    
                //using System.Windows.Threading; //From WindowsBase dll
                DispatcherHookEventHandler onOperationCompleted = (s, e) =>
                {
                    // this should be fired on the Dispather thread
                    Debug.Assert(Thread.CurrentThread == dispatcher.Thread);
    
                    // do an instant handle check
                    var nativeResult = WaitForSingleObject(handles[0], 0);
                    if (nativeResult == WAIT_OBJECT_0)
                        result = true;
                    else if (nativeResult == WAIT_ABANDONED_0)
                        throw new AbandonedMutexException(-1, handle);
                    else if (getTimeout() == 0)
                        result = false;
                    else if (nativeResult == WAIT_TIMEOUT)
                        return;
                    else
                        throw new InvalidOperationException("WaitForSingleObject");
    
                    // end the nested Dispatcher loop
                    frame.Continue = false;
                };
    
                EventHandler onDispatcherInactive = (s, e) =>
                {
                    operationPendingMre.Reset();
    
                    // wait for the handle or a message
                    var timeout = getTimeout();
    
                    var nativeResult = MsgWaitForMultipleObjectsEx(
                         (uint)handles.Length, handles,
                         timeout,
                         QS_EVENTMASK,
                         MWMO_INPUTAVAILABLE);
    
                    if (nativeResult == WAIT_OBJECT_0)
                        // handle signalled
                        result = true;
                    else if (nativeResult == WAIT_TIMEOUT)
                        // timed out
                        result = false;
                    else if (nativeResult == WAIT_ABANDONED_0)
                        // abandonded mutex
                        throw new AbandonedMutexException(-1, handle);
                    else if (nativeResult == WAIT_OBJECT_0 + 1)
                        // operation posted from another thread, yield to the frame loop
                        return;
                    else if (nativeResult == WAIT_OBJECT_0 + 2)
                    {
                        // a Windows message 
                        if (getTimeout() > 0)
                        {
                            // message pending, yield to the frame loop
                            enqueIdleOperation();
                            return;
                        }
    
                        // timed out
                        result = false;
                    }
                    else
                        // unknown result
                        throw new InvalidOperationException("MsgWaitForMultipleObjectsEx");
    
                    // end the nested Dispatcher loop
                    frame.Continue = false;
                };
    
                dispatcher.Hooks.OperationCompleted += onOperationCompleted;
                dispatcher.Hooks.OperationPosted += onOperationPosted;
                dispatcher.Hooks.DispatcherInactive += onDispatcherInactive;
    
                try
                {
                    // onDispatcherInactive will be called on the new frame,
                    // as soon as Dispatcher becomes idle
                    enqueIdleOperation();
                    //using System.Windows.Threading; //From WindowsBase dll
                    Dispatcher.PushFrame(frame);
                }
                finally
                {
                    if (idleOperation != null)
                        idleOperation.Abort();
                    dispatcher.Hooks.OperationCompleted -= onOperationCompleted;
                    dispatcher.Hooks.OperationPosted -= onOperationPosted;
                    dispatcher.Hooks.DispatcherInactive -= onDispatcherInactive;
                }
    
                return result;
            }
        }
    
        const uint QS_EVENTMASK = 0x1FF;
        const uint MWMO_INPUTAVAILABLE = 0x4;
        const uint WAIT_TIMEOUT = 0x102;
        const uint WAIT_OBJECT_0 = 0;
        const uint WAIT_ABANDONED_0 = 0x80;
        const uint INFINITE = 0xFFFFFFFF;
    
        [DllImport("user32.dll", SetLastError = true)]
        static extern uint MsgWaitForMultipleObjectsEx(
            uint nCount, IntPtr[] pHandles,
            uint dwMilliseconds, uint dwWakeMask, uint dwFlags);
    
        [DllImport("kernel32.dll")]
        static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);
    }
    #endregion
    
    公共部分类表单1:表单
    {
    int logNumber=0;
    公共表格1()
    {
    初始化组件();
    }
    私有void Form1\u加载(对象发送方、事件参数e)
    {
    WriteLogFunction(“**”);
    尝试
    {
    while(true)
    {
    WriteLogFunction(“**”);
    MessagePumpHelper.PumpMessage(1000);
    WriteLogFunction(“>>”);
    }
    }
    捕获(例外情况除外)
    {
    WriteLogFunction(例如消息);
    WriteLogFunction(例如InnerException.ToString());
    }
    }
    私有void WriteLogFunction(字符串strMessage)
    {
    string fileName=“MYLog_”+DateTime.Now.ToString(“yyyyMMMMdd”);
    文件名=文件名+“.txt”;
    使用(StreamWriter w=File.AppendText(文件名))
    {
    w、 WriteLine(“\r\n{0}….{1}+{2}ms>>>{3}”、logNumber.ToString()、DateTime.Now.ToLongTimeString()、DateTime.Now.millis秒.ToString()、strMessage);
    logNumber++;
    }
    }
    }
    #区域等待文本
    公共静态类MessagePumpHelper
    {
    公共静态无效PumpMessage(int毫秒Swait)
    {
    var虚拟=新的手动重置事件(假);
    WaitExt.WaitOne和泵(虚拟,毫秒SWAIT);
    }
    }
    //WaitOneAndPump
    公共静态类WaitExt
    {
    公共静态bool WAITONE和PUMP(此WaitHandle句柄,int毫秒)
    {
    使用(var operationPendingMre=新手动重置事件(错误))
    {
    var结果=假;
    var startTick=Environment.TickCount;
    //使用System.Windows.Threading;//从WindowsBase dll
    var dispatcher=dispatcher.CurrentDispatcher;
    var frame=新DispatcherFrame();
    变量句柄=新[]{
    handle.SafeWaitHandle.DangerousGetHandle(),
    operationPendingMre.SafeWaitHandle.DangerousGetHandle()};
    //空闲处理管道
    //使用System.Windows.Threading;//从WindowsBase dll
    DispatcherOperation idleOperation=null;
    动作idleAction=()=>{idleOperation=null;};
    动作ENQUEIDLEOOPTION=()=>
    {
    if(idleOperation!=null)
    idleOperation.Abort();
    //发布一个空操作以确保
    //将再次调用OnDispatcherActive
    idleOperation=dispatcher.BeginInvoke(
    无所事事,
    DispatcherPriority.ApplicationIdle);
    };
    //超时管道
    Func-getTimeout;
    if(Timeout.Infinite==毫秒计时)
    getTimeout=()=>无限;
    其他的
    getTimeout=()=>(uint)Math.Max(0,毫秒刺激+startTick-Environment.TickCount);
    //使用System.Windows.Threading;//从WindowsBase dll
    DispatcherHookEventHandler onOperationPosted=(s,e)=>
    {
    //这可能发生在随机线程上,
    //触发一个助手事件并
    //取消阻止OnDispatcherActive中的MsgWaitForMultipleObjectsEx
    operationPendingMre.Set();
    };
    //使用System.Windows.Threading;//从WindowsBase dll
    DispatcherHookEventHandler onOperationCompleted=(s,e)=>
    {
    //这应该在Dispather线程上激发
    Assert(Thread.CurrentThread==dispatcher.Thread);
    //做一个即时手柄检查
    var nativeResult=WaitForSingleObject(句柄[0],0);
    if(nativeResult==WAIT\u OBJECT\u 0)
    结果=真;
    else if(nativeResult==等待\u放弃\u 0)
    抛出新的废弃MutexException(-1,句柄);
    else if(getTimeout()==0)
    结果=假;
    else if(nativeResult==等待\u超时)
    返回;
    其他的
    抛出新的InvalidOperationException(“WaitForSingleObject”);
    //结束嵌套的调度程序循环
    frame.Continue=false;
    };
    EventHandler onDispatcherInactive=(s,e)=>
    {
    operationPendingMre.Reset();
    //等待句柄或消息
    var timeout=getTimeout();