转自:https://social.msdn.microsoft.com/Forums/zh-CN/6398fb10-ecc2-4c03-ab25-d03544f5fcc9/22914203093575320854201823244731243385443425530340200273138321?forum=visualcshartzhchs
我要实现的功能如下: 打开程序的时候先检查,如果这个程序已经在运行了,就直接将以前打开的程序窗口正常显示出来就行了。
我的代码如下,但隐藏的窗口不能显示出来,请问怎么改?
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; using System.Diagnostics; using System.Reflection; namespace 例子01 { static class Program { [DllImport("User32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int cmdShow); [DllImport("User32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd); private const int WS_SHOWNORMAL = 1; /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Process instance = RunningInstance(); if (instance == null) { Application.Run(new Form1()); } else { MessageBox.Show("程序已在运行中", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information); HandleRunningInstance(instance); } } /// <summary> /// 获取正在运行的实例,没有运行的实例返回null; /// </summary> public static Process RunningInstance() { Process current = Process.GetCurrentProcess(); Process[] processes = Process.GetProcessesByName(current.ProcessName); foreach (Process process in processes) { if (process.Id != current.Id) { if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName) { return process; } } } return null; } /// <summary> /// 显示已运行的程序。 /// </summary> public static void HandleRunningInstance(Process instance) { ShowWindow(instance.MainWindowHandle, WS_SHOWNORMAL); //显示,可以注释掉 SetForegroundWindow(instance.MainWindowHandle); //放到前端 } } }
你这个代码我在博客园看到了,文章中已经明确指出 “只有窗口最小化的时候可以达到此效果,如果隐藏到托盘则无法将打开的程序显示到桌面”,所以你上面的代码根本无法达到你的目的的,要实现你说的需求你需要用到FindWindow 函数,具体实现代码如下:
static class Program { [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll ", SetLastError = true)] static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)] public static extern int ShowWindow(IntPtr hwnd, int nCmdShow); public const int SW_RESTORE=9; public static IntPtr formhwnd; static Form1 form = null; ///<summary> /// 应用程序的主入口点。 ///</summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); string proc = Process.GetCurrentProcess().ProcessName; Process[] processes = Process.GetProcessesByName(proc); if (processes.Length <= 1) { form = new Form1(); Application.Run(form); } else { for (int i = 0; i < processes.Length; i++) { if (processes[i].Id != Process.GetCurrentProcess().Id) { if (processes[i].MainWindowHandle.ToInt32() == 0) { formhwnd = FindWindow(null, "Form1"); ShowWindow(formhwnd,SW_RESTORE); SwitchToThisWindow(formhwnd, true); } else { SwitchToThisWindow(processes[i].MainWindowHandle, true); } } } } } }
需要注意:
是可以的,不过要注意一点就是下面这句代码中的"Form1",放到自己的程序中要注意替换。这里要替换为 “目标窗体”的标题,即目标窗体的 Text 属性中的字符串。