zoukankan      html  css  js  c++  java
  • 窗体托盘后台运行

    winform代码:

    public partial class Form1 : Form
        {
            //这里在窗体上没有拖拽一个NotifyIcon控件,而是在这里定义了一个变量  
            private NotifyIcon notifyIcon = null;
    
            public Form1()
            {
                InitializeComponent();
                //调用初始化托盘显示函数  
                InitialTray();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                //这里写其他代码  
            }
    
            /// <summary>  
            /// 窗体关闭的单击事件  
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = true;
                //通过这里可以看出,这里的关闭其实不是真正意义上的“关闭”,而是将窗体隐藏,实现一个“伪关闭”  
                this.Hide();
            }
    
            private void InitialTray()
            {
                //隐藏主窗体  
                this.Hide();
    
                //实例化一个NotifyIcon对象  
                notifyIcon = new NotifyIcon();
                //托盘图标气泡显示的内容  
                notifyIcon.BalloonTipText = "正在后台运行";
                //托盘图标显示的内容  
                notifyIcon.Text = "窗体托盘后台运行测试程序";
                //注意:下面的路径可以是绝对路径、相对路径。但是需要注意的是:文件必须是一个.ico格式  
                string str = System.Windows.Forms.Application.StartupPath;
                notifyIcon.Icon = new System.Drawing.Icon(str+"/logo.ico");
                
                //true表示在托盘区可见,false表示在托盘区不可见  
                notifyIcon.Visible = true;
                //气泡显示的时间(单位是毫秒)  
                notifyIcon.ShowBalloonTip(3000);
                notifyIcon.MouseClick += new System.Windows.Forms.MouseEventHandler(notifyIcon_MouseClick);
    
                ////设置二级菜单  
                //MenuItem setting1 = new MenuItem("二级菜单1");  
                //MenuItem setting2 = new MenuItem("二级菜单2");  
                //MenuItem setting = new MenuItem("一级菜单", new MenuItem[]{setting1,setting2});  
    
                //帮助选项,这里只是“有名无实”在菜单上只是显示,单击没有效果,可以参照下面的“退出菜单”实现单击事件  
                MenuItem help = new MenuItem("帮助");
                help.Click += new EventHandler(help_Click);
                //关于选项  
                MenuItem about = new MenuItem("关于");
                about.Click += new EventHandler(about_Click);
                //退出菜单项  
                MenuItem exit = new MenuItem("退出");
                exit.Click += new EventHandler(exit_Click);
    
                ////关联托盘控件  
                //注释的这一行与下一行的区别就是参数不同,setting这个参数是为了实现二级菜单  
                //MenuItem[] childen = new MenuItem[] { setting, help, about, exit };  
                MenuItem[] childen = new MenuItem[] { help, about, exit };
                notifyIcon.ContextMenu = new ContextMenu(childen);
    
                //窗体关闭时触发  
                this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
            }
    
            /// <summary>  
            /// 鼠标单击  
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void notifyIcon_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                //鼠标左键单击  
                if (e.Button == MouseButtons.Left)
                {
                    //如果窗体是可见的,那么鼠标左击托盘区图标后,窗体为不可见  
                    if (this.Visible == true)
                    {
                        this.Visible = false;
                    }
                    else
                    {
                        this.Visible = true;
                        this.Activate();
                    }
                }
            }
    
            /// <summary>  
            /// 退出选项  
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void exit_Click(object sender, EventArgs e)
            {
                //退出程序  
                System.Environment.Exit(0);
            }
    
            /// <summary>  
            /// 关于选项  
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void about_Click(object sender, EventArgs e)
            {
                MessageBox.Show("===By技术部 KK===");
            }
            /// <summary>  
            /// 帮助选项  
            /// </summary>  
            /// <param name="sender"></param>  
            /// <param name="e"></param>  
            private void help_Click(object sender, EventArgs e)
            {
                MessageBox.Show("===详情请联系技术部===");
            }
        }  
    View Code

    InteropHelper 弹窗

        //交互操作  //弹窗         
        //调用
        //InteropHelper.ShowMessageBox("This a message from AlertService.","AlertService Message");
        //string path = System.Windows.Forms.Application.StartupPath;
        //Interop.CreateProcess("Quartz.Net.WinForm.exe", path + "\");
        public class InteropHelper
        {
            public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
            public static void ShowMessageBox(string message, string title)
            {
                int resp = 0;
                WTSSendMessage(
                    WTS_CURRENT_SERVER_HANDLE,
                    WTSGetActiveConsoleSessionId(),
                    title, title.Length,
                    message, message.Length,
                    0, 0, out resp, false);
            }
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern int WTSGetActiveConsoleSessionId();
            [DllImport("wtsapi32.dll", SetLastError = true)]
            public static extern bool WTSSendMessage(
                IntPtr hServer,
                int SessionId,
                String pTitle,
                int TitleLength,
                String pMessage,
                int MessageLength,
                int Style,
                int Timeout,
                out int pResponse,
                bool bWait);
    
            public static void CreateProcess(string app, string path)
            {
                IntPtr hToken;
                IntPtr hDupedToken = IntPtr.Zero;
    
                PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
                sa.Length = Marshal.SizeOf(sa);
    
                STARTUPINFO si = new STARTUPINFO();
                si.cb = Marshal.SizeOf(si);
    
                int dwSessionID = WTSGetActiveConsoleSessionId();
                bool result = WTSQueryUserToken(dwSessionID, out hToken);
    
                if (!result)
                {
                    ShowMessageBox("WTSQueryUserToken failed", "AlertService Message");
                }
    
                result = DuplicateTokenEx(
                      hToken,
                      GENERIC_ALL_ACCESS,
                      ref sa,
                      (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification,
                      (int)TOKEN_TYPE.TokenPrimary,
                      ref hDupedToken
                   );
    
                if (!result)
                {
                    ShowMessageBox("DuplicateTokenEx failed", "AlertService Message");
                }
    
                IntPtr lpEnvironment;
                result = CreateEnvironmentBlock(out lpEnvironment, hDupedToken, false);
    
                if (!result)
                {
                    ShowMessageBox("CreateEnvironmentBlock failed", "AlertService Message");
                }
    
                result = CreateProcessAsUser(
                            hDupedToken,
                            path + app,
                            String.Empty,
                            ref sa, ref sa,
                            false, 0, IntPtr.Zero,
                            path, ref si, ref pi);
    
                if (!result)
                {
                    int error = Marshal.GetLastWin32Error();
                    string message = String.Format("CreateProcessAsUser Error: {0}", error);
                    ShowMessageBox(message, "AlertService Message");
                }
    
                if (pi.hProcess != IntPtr.Zero)
                    CloseHandle(pi.hProcess);
                if (pi.hThread != IntPtr.Zero)
                    CloseHandle(pi.hThread);
                if (hDupedToken != IntPtr.Zero)
                    CloseHandle(hDupedToken);
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct STARTUPINFO
            {
                public Int32 cb;
                public string lpReserved;
                public string lpDesktop;
                public string lpTitle;
                public Int32 dwX;
                public Int32 dwY;
                public Int32 dwXSize;
                public Int32 dwXCountChars;
                public Int32 dwYCountChars;
                public Int32 dwFillAttribute;
                public Int32 dwFlags;
                public Int16 wShowWindow;
                public Int16 cbReserved2;
                public IntPtr lpReserved2;
                public IntPtr hStdInput;
                public IntPtr hStdOutput;
                public IntPtr hStdError;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct PROCESS_INFORMATION
            {
                public IntPtr hProcess;
                public IntPtr hThread;
                public Int32 dwProcessID;
                public Int32 dwThreadID;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            public struct SECURITY_ATTRIBUTES
            {
                public Int32 Length;
                public IntPtr lpSecurityDescriptor;
                public bool bInheritHandle;
            }
    
            public enum SECURITY_IMPERSONATION_LEVEL
            {
                SecurityAnonymous,
                SecurityIdentification,
                SecurityImpersonation,
                SecurityDelegation
            }
    
            public enum TOKEN_TYPE
            {
                TokenPrimary = 1,
                TokenImpersonation
            }
    
            public const int GENERIC_ALL_ACCESS = 0x10000000;
    
            [DllImport("kernel32.dll", SetLastError = true,
                CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern bool CloseHandle(IntPtr handle);
    
            [DllImport("advapi32.dll", SetLastError = true,
                CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
            public static extern bool CreateProcessAsUser(
                IntPtr hToken,
                string lpApplicationName,
                string lpCommandLine,
                ref SECURITY_ATTRIBUTES lpProcessAttributes,
                ref SECURITY_ATTRIBUTES lpThreadAttributes,
                bool bInheritHandle,
                Int32 dwCreationFlags,
                IntPtr lpEnvrionment,
                string lpCurrentDirectory,
                ref STARTUPINFO lpStartupInfo,
                ref PROCESS_INFORMATION lpProcessInformation);
    
            [DllImport("advapi32.dll", SetLastError = true)]
            public static extern bool DuplicateTokenEx(
                IntPtr hExistingToken,
                Int32 dwDesiredAccess,
                ref SECURITY_ATTRIBUTES lpThreadAttributes,
                Int32 ImpersonationLevel,
                Int32 dwTokenType,
                ref IntPtr phNewToken);
    
            [DllImport("wtsapi32.dll", SetLastError = true)]
            public static extern bool WTSQueryUserToken(
                Int32 sessionId,
                out IntPtr Token);
    
            [DllImport("userenv.dll", SetLastError = true)]
            static extern bool CreateEnvironmentBlock(
                out IntPtr lpEnvironment,
                IntPtr hToken,
                bool bInherit);
    
        }
    View Code

    参考:winForm窗体关闭按钮实现托盘后台运行(类似QQ托盘区运行)

  • 相关阅读:
    Asp.Net 合并图片(二维码和其他图片合并)
    Asp.Net 隐藏手机号中间四位为*方法
    Linux后台运行进程 node screen
    nginx 实现负载均衡
    Python 字典递归合并
    搭建Elasticsearch环境,logstash环境
    搭建Elasticsearch环境,搭建kibana 环境
    flask mysql sqlalchemy教程
    MySQL数据库+命令大全+常用操作
    Python开发单元测试,必不可少
  • 原文地址:https://www.cnblogs.com/systemkk/p/5261782.html
Copyright © 2011-2022 走看看