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("===详情请联系技术部==="); } }
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); }