以下API都尝试过...都不行;将已经最小化的程序激活弹出其窗口
SetForegroundWindow
SwitchToThisWindow
ShowWindowAsync
ShowWindow以上几个API本人都试过...我的程序是最小化到托盘的
当本程序已经打开时,如果程序已经运行了一个实例,就激活它,让它变成正常窗口显示;
如果程序没有运行的实例,就生成一个新的实例;/// <summary> 
        /// 该函数设置由不同线程产生的窗口的显示状态。 
        /// </summary> 
        /// <param name="hWnd">窗口句柄</param> 
        /// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分。</param> 
        /// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零。</returns> 
        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
        /**/
        /// <summary>
        /// 恢复一个最小化的程序,并将其激活
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <returns>非零表示成功,零表示失败</returns>
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool OpenIcon(IntPtr hWnd);        /**/
        /// <summary>
        /// 窗口是否已最小化
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <returns>非零表示成功,零表示失败</returns>
        [DllImport("User32.dll")]
        private static extern bool IsIconic(IntPtr hWnd);
        /// <summary> 
        /// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。 
        /// </summary> 
        /// <param name="hWnd">将被激活并被调入前台的窗口句柄。</param> 
        /// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零。</returns> 
        [DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("User32.dll")]
        private static extern IntPtr FindWindow(string strclassName, string strWindowName);        [DllImport("user32.dll", EntryPoint = "SwitchToThisWindow")]
        private static extern void SwitchToThisWindow(IntPtr hWnd, Boolean fAltTab);         private const int SW_HIDE = 0;           //隐藏窗口,活动状态给令一个窗口 
        private const int SW_SHOWNORMAL = 1;     //用原来的大小和位置显示一个窗口,同时令其进入活动状态 
        private const int SW_SHOWMINIMIZED = 2;  //最小化窗口,并将其激活 
        private const int SW_SHOWMAXIMIZED = 3;  //最大化窗口,并将其激活 
        private const int SW_SHOWNOACTIVATE = 4; //用最近的大小和位置显示一个窗口,同时不改变活动窗口 
        private const int SW_RESTORE = 9;        //用原来的大小和位置显示一个窗口,同时令其进入活动状态 
        private const int SW_SHOWDEFAULT = 10;   //根据默认 创建窗口时的样式 来显示        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Process instance = RunningInstance();
            if (instance == null)
            {
                Application.Run(new frmMain());
            }
            else
            {
                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)
        {
            int nIndex;            Process procCurrent = Process.GetCurrentProcess();
            Process[] procProgram = Process.GetProcessesByName("PC Smart");            /*   check   if   program   is   already   running   */
            if (procProgram.Length > 1)
            {
                for (nIndex = 0; nIndex < procProgram.Length; nIndex++)
                {
                    /*   switch   to   the   other   instance   and   let   this   one   die   */
                    if (procProgram[nIndex].Id != procCurrent.Id)
                        SwitchToThisWindow(procProgram[nIndex].MainWindowHandle, true);
                }
            }
            else
            {
                /*   enable   visual   style,   most   commonly   associated   with   the   XP   operating   system   */
                Application.EnableVisualStyles();
                Application.DoEvents();
                Application.Run(new frmMain());
            }               //Process[] prs = Process.GetProcesses();
            //Process thisone = Process.GetCurrentProcess();
            //foreach (Process pr in prs)
            //{
            //    if (thisone.ProcessName == pr.ProcessName && thisone.Id != pr.Id)
            //    {
            //        MessageBox.Show("程序已经运行", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //        SwitchToThisWindow(pr.MainWindowHandle, true);
            //        thisone.Kill();
            //    }
            //}
            //SwitchToThisWindow(instance.MainWindowHandle, true);   
            //ShowWindowAsync(instance.MainWindowHandle, SW_RESTORE); //显示,可以注释掉 
            //SetForegroundWindow(instance.MainWindowHandle);            //放到前端 
        }测试过,当程序不是最小化时,再打开该程序时,会置前....但最小化以后,运行没有反应!!!
研究N久了...哪位大侠做过???

解决方案 »

  1.   

    http://topic.csdn.net/u/20100310/23/1554e955-5ffc-4771-9034-09889c5b00e2.html
      

  2.   

    因为在设置 ShowInTaskBar 属性时 this.Handle 已经改变啦
    所以此时 instance.MainWindowHandle = 0
    这还搞个毛啊~ 所以,乖乖 FindWindow 吧
    private const int SW_HIDE = 0;
    private const int SW_RESTORE = 9;
    private const int SW_SHOWNA = 8;private const int GWL_EXSTYLE = -20;
    private const int WS_EX_APPWINDOW = 0x40000;[DllImport("user32.dll", EntryPoint = "GetClassNameA")]
    private static extern bool GetClassName(IntPtr hwnd, StringBuilder lpClassName, int nMaxCount);[DllImport("user32.dll", EntryPoint = "GetWindowLongA")]
    private static extern int GetWindowLong(IntPtr hwnd, int nIndex);[DllImport("user32.dll", EntryPoint = "FindWindowA")]
    private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.dll", EntryPoint = "SetForegroundWindow")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);[DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
    private static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);[DllImport("user32.dll", EntryPoint = "ShowWindowAsync")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);//===========================
    StringBuilder sb = new StringBuilder(255);if (GetClassName(this.Handle, sb, sb.Capacity))
    {
        // 区别窗口标题
        this.Text = Guid.NewGuid().ToString();    // "Form1" 窗口标题要改下
        IntPtr hwnd = FindWindow(sb.ToString(), "Form1");    if (this.Handle == hwnd) return;    int wlong = GetWindowLong(hwnd, GWL_EXSTYLE);    // 依据 ShowInTaskBar 判断是否需要隐藏窗口
        if ((wlong & WS_EX_APPWINDOW) == 0)
        {
            ShowWindowAsync(hwnd, SW_HIDE);
            wlong |= WS_EX_APPWINDOW;
            SetWindowLong(hwnd, GWL_EXSTYLE, wlong);
        }
        ShowWindowAsync(hwnd, SW_SHOWNA | SW_RESTORE);
        SetForegroundWindow(hwnd);
    }// 如果要设置多个窗口可以用
    // GetNextWindow + GetDesktopWindow + GetClassName + 判断 hwnd != this.Handle
      

  3.   

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.IO;
    using System.Security.Permissions;
    namespace WindowsApplication7
    {
        static class Program
        {
            /// <summary>
            /// 应用程序的主入口点。
            /// </summary>
            [STAThread]
            static void Main()
            {
                bool bResult;
                System.Threading.Mutex mutex = new System.Threading.Mutex(true, "425D04", out bResult);
                if (!bResult)
                {
                    IntPtr hHandle = OpenFileMapping(FILE_MAP_READ, 0, "05A79C");
                    IntPtr lpAddress = MapViewOfFile(hHandle, FILE_MAP_READ, 0, 0, 0);
                    IntPtr hWnd = new IntPtr(Marshal.ReadInt32(lpAddress));
                    ShowWindow(hWnd, SW_SHOWNORMAL);
                    SetForegroundWindow(hWnd);
                }
                else
                {                Application.EnableVisualStyles();
                    Application.SetCompatibleTextRenderingDefault(false);
                    Form1 frm = new Form1();                SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
                    sa.nLength = 12;
                    sa.lpSecurityDescriptor = 0;
                    sa.bInheritHandle = 1;                IntPtr hHandle = CreateFileMapping(-1, ref sa, PAGE_READWRITE, 0, 4, "05A79C");
                    IntPtr lpAddress = MapViewOfFile(hHandle, FILE_MAP_WRITE, 0, 0, 0);
                    Marshal.WriteInt32(lpAddress, frm.Handle.ToInt32());
                    Application.Run(frm);
                    CloseHandle(hHandle);
                }
            }
            [DllImport("Kernel32.dll", EntryPoint = "CreateFileMapping")]
            private extern static IntPtr CreateFileMapping(Int32 hFile,
                                                ref SECURITY_ATTRIBUTES lpFileMappingAttributes,
                                                Int32 flProtect, Int32 dwMaximumSizeHigh,
                                                Int32 dwMaximumSizeLow,
                                                string lpName);
            [DllImport("Kernel32.dll", EntryPoint = "OpenFileMapping")]
            private extern static IntPtr OpenFileMapping(Int32 dwDesiredAccess, Int32 bInheritHandle, string lpName);        [DllImport("Kernel32.dll")]
            private extern static IntPtr MapViewOfFile(IntPtr hFileMappingObject, Int32 dwDesiredAccess,
                                                Int32 dwFileOffsetHigh,
                                                Int32 dwFileOffsetLow,
                                                Int32 dwNumberOfBytesToMap);
            [DllImport("kernel32.dll")]
            private extern static bool CloseHandle(IntPtr hHandle);
            [DllImport("User32.dll")]
            private extern static bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
            [DllImport("user32.dll")]
            public static extern int SetForegroundWindow(IntPtr hwnd);
            private const Int32 PAGE_READWRITE = 0x04;
            private const Int32 FILE_MAP_WRITE = 0x02;
            private const Int32 FILE_MAP_READ = 0x04;
            private const Int32 SW_SHOWNORMAL = 0x01;    }
        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public Int32 nLength;
            public Int32 lpSecurityDescriptor;
            public Int32 bInheritHandle;
        }
    }
      

  4.   

    只要程序没有最小化到托盘一切成功...
    但最小化到托盘以后,就没办法再激活显示了!!!求原码~~~本人写不好!
    大侠请发邮箱 :[email protected]
      

  5.   

    托盘后的程序获取不到MainWindowHandle...就是这个问题了!!!