转自: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. selenium中iframe的切换

    #第一层是默认层, 第二层是新建标签的层,第三层是百度的那层from selenium import webdriverimport timedriver=webdriver.Chrome()driv ...

  2. 单例模式 | 程序员都想要探索的 Javascript 设计模式

    最近打算系统的学习 Javascript 设计模式,以便自己在开发中遇到问题可以按照设计模式提供的思路进行封装,这样可以提高开发效率并且可以预先规避很多未知的问题. 先从最基本的单例模式开始 什么是单 ...

  3. python实现批量压缩文件夹

    前段时间碰到一个需要把目录下文件夹压缩的项目,但是度娘里没找到,只好自己写脚本了. #coding:utf-8 import os filePath = raw_input("请输入路径:& ...

  4. Virtualization Essentials---Understanding hypervisor

    Original link from : http://searchservervirtualization.techtarget.com/tip/Understanding-hosted-and-b ...

  5. Arm11-mini6410入坑

    Mini6410 学习Stm32的时候原子哥的资料真全啊,而且原子哥在他论坛也解答问题.然而现在学习ARM买了一套友善之臂的开发板,官方的资料只能刚好入门而已,其实入门都算不上.看了一下,网上的资料很 ...

  6. Qt自定义控件系列(一) --- 圆形进度条

    本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...

  7. 最新版本汉化-PowerDesigner 16.6 汉化并河蟹

    更新日志: 2019-03-14 V1.1 1.支持反复多次汉化: 2.修复少许bug. 最新的16.6版本已经在汉化中了,基本上所有的菜单均已汉化完成,部分窗体还没有编译通过. 不过,不影响尝鲜使用 ...

  8. 手把手:使用service principal连接Azure Media Service

    在简书中查看,请点击我. 关于相关内容解释,请参考docs文档 https://docs.microsoft.com/en-us/azure/media-services/previous/media ...

  9. Django models 的字段类型

    1.models.AutoField   ---自增列 = int(11)    如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_k ...

  10. java语言基础--方法的执行图解

    1.调用m1方法(压栈) 2.m1调用m2方法(压栈) 3.m2调用m3方法(压栈) 4.运行m3(弹栈) 5.运行m2(弹栈) 6.运行m1(弹栈)