转自: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 属性中的字符串

c# 程序只能运行一次(多次运行只能打开同一个程序)的更多相关文章

  1. 在文件夹中 的指定类型文件中 查找字符串(CodeBlocks+GCC编译,控制台程序,仅能在Windows上运行)

    说明: 程序使用 io.h 中的 _findfirst 和 _findnext 函数遍历文件夹,故而程序只能在 Windows 下使用. 程序遍历当前文件夹,对其中的文件夹执行递归遍历.同时检查遍历到 ...

  2. [转]C#程序无法在64位系统上运行之.NET编译的目标平台

    今天将编译的C#的exe拷贝到测试机上(Win7_64bit),一运行就挂了,提示“stop working”,一开始怀疑测试机上没有安装.net framework框架,追究半天原来是编译的目标平台 ...

  3. (转载)用VS2012或VS2013在win7下编写的程序在XP下运行就出现“不是有效的win32应用程序“

    原文地址:http://www.vcerror.com/?p=1483 问题描述: 用VC2013编译了一个程序,在Windows 8.Windows 7(64位.32位)下都能正常运行.但在Win ...

  4. vs2005 ,2008,2010中引入app.manifest(即c#程序在win7下以管理员权限运行方法)

    打开VS2005.VS2008.VS2010工程,查看工程文件夹中的Properties文件夹下是否有app.manifest这个文件:如没有,按如下方式创建:鼠标右击工程在菜单中选择“属性”,点击工 ...

  5. 干净win7要做几步才能运行第一个Spring MVC 写的动态web程序

    干净win7要做几步才能运行第一个Spring MVC 写的动态web程序: 1. 下载安装jdk 2. 配置Java环境变量 3. 测试一下第1,2两步是否完全成功:http://jingyan.b ...

  6. Ubuntu16.04下写的Qt程序,调试时没问题,运行时偶现崩溃 (需要在运行时生成core dump文件,QMAKE_CC += -g)

    记录一下 Ubuntu16.04下写的Qt程序,调试时没问题,运行时偶现崩溃 需要在运行时生成core dump文件 首先在pro结尾里加入 QMAKE_CC += -g QMAKE_CXX += - ...

  7. ARM裸板开发:04_MMU 链接地址与运行地址不一致时,(SDRAM)初始化程序地址无关码问题的分析

    ARM裸板开发过程,程序的链接地址设置为为0x30000000,而前期的启动代码以及相关硬件的初始化代码需要在内部iRAM(steppingstone,起始地址0x0)的4K中运行.链接地址与运行地址 ...

  8. 在“开始”菜单中的“运行”一栏输入特定命令打开windows程序

    winver 检查Windows版本   wmimgmt.msc 打开Windows管理体系结构(wmi)   wupdmgr Windows更新程序   wscript Windows脚本宿主设置 ...

  9. IntelliJ IDEA编写的spark程序在远程spark集群上运行

    准备工作 需要有三台主机,其中一台主机充当master,另外两台主机分别为slave01,slave02,并且要求三台主机处于同一个局域网下 通过命令:ifconfig 可以查看主机的IP地址,如下图 ...

随机推荐

  1. 1023. Have Fun with Numbers (20)

    生词以及在文中意思 duplication 重复 permutation 排列 property 属性 import java.util.Scanner; public class Main { pu ...

  2. FCC-js算法题解题笔记

    题目链接:https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm ...

  3. python并发_进程_multiprocessing

    多进程基础, 主要是用了 multiprocessing模块 : 在一个python进程中开启子进程,start方法和并发效果. import time from multiprocessing im ...

  4. javap反汇编的使用

    javap可以查看class文件信息,灵活的运用javap,让你更好的理解class类文件结构信息等   方法/步骤     javap -help查看命令帮助   javap -package Te ...

  5. python编程从入门到实践 alien invasion 项目源码

    现在上传一个 python编程从入门到实践 alien invasion 项目源码 以供大家学习参考 跟官方版本可能不太一样,因为是自己写的 也算是给新手一个参考 我用的环境是pycharm 可能需要 ...

  6. callback回调函数的理解

    callback采用的设计模式是:模板模式,他的设计理念是基于面向对象中的多态的. 我们的程序中走到某个地方他会出现不一样的动作的时候,我们在这儿就使用回调函数.我们利用的就是 多态的原理,我们传递不 ...

  7. .NET并行计算和并发11:并发接口 IProducerConsumerCollection

    using System; using System.Collections; using System.Collections.Generic; using System.Collections.C ...

  8. Application对象及常用方法

    Application对象: 服务器启动后,就产生了这个application对象.当一个客户访问服务器上的一个JSP页面时,JSP引擎为该客户分配这个 application对象,当客户在所访问的网 ...

  9. 用powermock 方法中new对象

    在单元测试中有时需要对方法体内new出来的对象进行方法隔离,powermock提供了这个功能,下面是一个段样例代码: UserBean user = mock(UserBean.class, RETU ...

  10. CodeBlocks无法调试的解决方法

    闲话: 万万没想到我也会写这个东西.一开始软件工程课的时候老师要求我们写博客园,一直都是被动地在写博客.刚刚在重温C语言的时候发现的各种各样问题觉得还是写下来比较好,一旦以后自己又忘了呢……(摊手 顺 ...