c#中让Windows窗体只运行一次,并在第二次启动窗体时激活该窗体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#中让Windows窗体只运行一次,并在第二次启动窗体时激活该窗体相关的知识,希望对你有一定的参考价值。

不是MDI窗体,就一个单独的窗体
就像迅雷一样 迅雷在启动的时候点击关闭按钮就最小化到电脑的右下角了,然后在启动迅雷,却没有从新启动,而是把已经启动的迅雷激活了...请问用C#怎么实现。

参考技术A 方法一:

/// <summary>
/// 从这里开始运行
/// </summary>
[STAThread]
static void Main()

Process instance = RunningInstance();
if (instance == null)

//没有实例在运行
WeatherApp appInstance = new WeatherApp();
appInstance.StartMainGui();

else

//已经有一个实例在运行
HandleRunningInstance(instance);


#region 确保只有一个实例
public static Process RunningInstance()

Process current = Process.GetCurrentProcess();
Process[] processes = Process.GetProcessesByName(current.ProcessName);
//遍历与当前进程名称相同的进程列表
foreach (Process process in processes)

//Ignore the current process
if (process.Id != current.Id)

//Make sure that the process is running from the exe file.
if (Assembly.GetExecutingAssembly().Location.Replace("/", "\\") == current.MainModule.FileName)

//Return the other process instance.
return process;



return null;

private static void HandleRunningInstance(Process instance)

MessageBox.Show("该应用系统已经在运行!", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
ShowWindowAsync(instance.MainWindowHandle, 1); //调用api函数,正常显示窗口
SetForegroundWindow(instance.MainWindowHandle); //将窗口放置最前端。

[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(System.IntPtr hWnd);
#endregion

方法二:

[STAThread]
static void Main(string[] args)

bool isFirst;

System.Threading.Mutex mutex = new System.Threading.Mutex(true, "WindowAppTest", out isFirst);
//这里的myApp是程序的标识,建议换成你的程序的物理路径,这样的话如果在一个操作系统中这个标志不会和其它程序冲突
if (!isFirst)

MessageBox.Show("Exist");
Environment.Exit(1);//实例已经存在,退出程序

else

Application.Run(new Form1());



方法三
把AssemblyInfo.cs里的[assembly: AssemblyFileVersion("1.0.0.0")]改为[assembly:AssemblyFileVersion("2.0.0.8")],然后利用该信息进行判断。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.Collections;
using System.Threading;

namespace MyWork_01

class Program

static void Main(string[] args)

Process[] processes = Process.GetProcesses(); //获得当前所有进程
Process currentProcess = Process.GetCurrentProcess(); //获取当前正在运行进程
ProcessModule currentPM = currentProcess.Modules[0];
int same = 0; //相同运行实例个数
ArrayList proList = new ArrayList(); //将相同实例加入此集合中

foreach (Process p in processes)

try//由于进程不同,有的进程不包含Modules信息,所以要用try保护

if (p.Modules != null)
if (p.Modules.Count > 0)

System.Diagnostics.ProcessModule pm = p.Modules[0];
if (pm.FileVersionInfo.FileVersion.Equals(currentPM.FileVersionInfo.FileVersion))

same++;
proList.Add(p);

if (same > 1)

same++;
proList.Add(p);
if (same > 1)

for (int i = 0; i < proList.Count; i++)

if (((Process)(proList[i])).Id == currentProcess.Id)

Console.WriteLine("该进程已经启动了一个实例");
Thread.Sleep(1000);
((Process)(proList[i])).Kill();






catch


Console.Read();




方法四:直接定义一个属性类,利用此属性信息进行判断。
代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.Threading;

[assembly: Help("This Assembly demonstrates custom attributes creation and their run-time query.")]

public class HelpAttribute : Attribute

public HelpAttribute(String Description_in)

this.description = Description_in;


protected String description;

public String Description

get

return this.description;



class Program

static void Main(string[] args)

HelpAttribute HelpAttr1 = null;
HelpAttribute HelpAttr2 = null;
Process currentProcess = Process.GetCurrentProcess(); //获取当前正在运行进程
Assembly a = Assembly.LoadFrom(currentProcess.MainModule.FileName);
foreach (Attribute attr in a.GetCustomAttributes(true))

HelpAttr1 = attr as HelpAttribute;
if (null != HelpAttr1)

//Console.WriteLine("Description of 0:\n1", currentProcess.MainModule.FileName, HelpAttr1.Description);
break;


Process[] processes = Process.GetProcesses(); //获得当前所有进程
int same = 0; //相同运行实例个数
ArrayList proList = new ArrayList(); //将相同实例加入此集合中
foreach (Process pro in processes)

try//由于进程不同,有的进程不包含Modules信息,所以要用try保护

if (pro.Modules != null)
if (pro.Modules.Count > 0)

Assembly b = Assembly.LoadFrom(pro.MainModule.FileName);
foreach (Attribute attr in b.GetCustomAttributes(true))

HelpAttr2 = attr as HelpAttribute;
if (null != HelpAttr2)

if (HelpAttr1.Description.Equals(HelpAttr2.Description))

same++;
proList.Add(pro);
if (same > 1)

for (int i = 0; i < proList.Count; i++)

if (((Process)(proList[i])).Id == currentProcess.Id )

Console.WriteLine("该进程已经启动了一个实例");

Thread.Sleep(1000);
((Process)(proList[i])).Kill();









catch



Console.ReadLine();


本回答被提问者采纳
参考技术B 点下面有个 激活MDI就好了

在第二次按下时更改标签栏按钮的行为

【中文标题】在第二次按下时更改标签栏按钮的行为【英文标题】:Change tabbar button behaviour on second press 【发布时间】:2017-11-11 18:51:24 【问题描述】:

我在 react native 项目 (0.43.3) 中使用路由器通量

如何在第一次按下图标时切换选项卡并在第二次按下时重置此选项卡上的堆栈?

例子:

1. In: tab1
2. Press tab2-icon => switch to tab2 (scene tab2 must be showed)
3. Press tab1-icon => switch to tab1 (scene tab1 must be showed, just as it had been)
4. Press tab1-icon => switch to tab1 (scene tab 1 must be reload with a different prop)

我尝试将动作添加到 onPress &lt;Scene onPress=() =&gt; /* CODE */ ...&gt; 的场景中,但丢失(覆盖或替换)路由器通量标签栏自己的动作(如显示场景组件,标记为活动,更改标签栏项目的颜色)。 也许如果我可以在 onPress y 默认值中按下 tabbar 时添加操作,然后我的代码会这样做


@mantir 在 repo 中的原始问题:https://github.com/aksonov/react-native-router-flux/issues/1905

【问题讨论】:

【参考方案1】:

3.39.1 开始,您应该可以使用 onActivePress 来处理它。 正如this pullRequest 中的解释,当标签已被选中时触发!

【讨论】:

感谢保罗!!这是我一直在寻找的功能。 3.39.2 有什么问题?我一直在使用 3.38.0,我更新到 3.39.2,但我收到重复名称的错误:Failed to build DependencyGraph: @providesModule naming collision: Duplicate module name: 我的依赖项是:`“react”:“16.0.0-alpha.6”,“react-native” :“0.43.3”,“react-native-router-flux”:“3.38.0”,“react-native-vector-icons”:“^4.0.1”` 嗨!我现在不停留在 3.38.0 中,因为我现在不需要此功能。它应该链接到“重复的模块名称”。我在 react-native-vectore-icons 遇到了这样的麻烦!很高兴能帮到你✌️

以上是关于c#中让Windows窗体只运行一次,并在第二次启动窗体时激活该窗体的主要内容,如果未能解决你的问题,请参考以下文章

如何在c#中实现单击一个按钮后,再在窗体内点击一次鼠标,把该按钮移动到第二次点击的位置?

电子邮件附件的存储名称 - 第一次运行时出错,但在第二次运行时有效

系统互斥体的 AbandonedMutexException 在第一次运行被杀死时未在第二次运行中捕获

Xcode NSRangeException 在第二次运行代码时

jQuery 在第二次单击时删除类并在第二次单击时禁用悬停

cordova/phonegap 1.6 在第二次发布时崩溃