建立单实例程序
看到愚翁的这篇文章《如何使自己的程序只运行一次》 ,感觉有点问题。第一种方法用互斥体可以实现单实例,但是无法操纵原来的窗口。第二种方法按程序名搜寻进程,只要程序改了名字,就可以运行好几次了。在下面的评论里他又给了另一个链接,是个外国人写的:http://www.codeproject.com/csharp/cssingprocess.asp。他综合了互斥体和搜寻进程,如果已经打开了程序,则把原来的窗口显示出来。其实已经比较完美了,但是还有点问题。如果我的程序改了名,就会找不到原来的进程,就没有办法把原来的窗口显示出来了。
在百度上搜索这方面的文章,看到这么一篇:《C# 单实例运行》,是在.NET 3.0中使用的,确实比较方便。
我觉得关键是应该用打开程序的PID来搜寻,这样肯定不会错。于是我修改了程序,在程序第一次运行的时候把它的PID写到一个文件中去,下一次再运行就从这个文件中找到打开窗口的PID。
再后来经人提醒可以用进程间通讯来获得PID,虽然程序麻烦了一点,但是不用再写文件了。下面是我写的程序完整代码:
这里面只涉及了很简单的情况,即单个窗口的情况。没有考虑MDI程序,在主窗口里面打开的情况。
在百度上搜索这方面的文章,看到这么一篇:《C# 单实例运行》,是在.NET 3.0中使用的,确实比较方便。
我觉得关键是应该用打开程序的PID来搜寻,这样肯定不会错。于是我修改了程序,在程序第一次运行的时候把它的PID写到一个文件中去,下一次再运行就从这个文件中找到打开窗口的PID。
再后来经人提醒可以用进程间通讯来获得PID,虽然程序麻烦了一点,但是不用再写文件了。下面是我写的程序完整代码:
1
namespace SingleInstance {
2
static class Program {
3
/**/
4
/// <summary>
5
/// 应用程序的主入口点。
6
/// </summary>
7
[STAThread]
8
static void Main() {
9
Application.EnableVisualStyles();
10
Application.SetCompatibleTextRenderingDefault(false);
11
bool bCreatedNew;
12
Mutex m = new Mutex(false, "myUniqueName", out bCreatedNew);
13
if (bCreatedNew) {
14
//实例化服务器信道
15
IpcServerChannel channel = new IpcServerChannel("ServerChannel");
16
//注册信道
17
ChannelServices.RegisterChannel(channel, false);
18
//注册服务类型
19
RemotingConfiguration.RegisterWellKnownServiceType(typeof(ProcessID), "ProcessID", WellKnownObjectMode.SingleCall);
20
Application.Run(new Form1());
21
}
22
else {
23
//建立客户端信道
24
IpcClientChannel channel = new IpcClientChannel();
25
//注册信道
26
ChannelServices.RegisterChannel(channel, false);
27
ProcessID obj = (ProcessID)Activator.GetObject(typeof(ProcessID), "ipc://ServerChannel/ProcessID");
28
int processID = obj.PID;
29
Process instance = Process.GetProcessById(processID);
30
HandleRunningInstance(instance);
31
}
32
}
33
public static void HandleRunningInstance(Process instance) {
34
//还原窗口
35
if (IsIconic(instance.MainWindowHandle))
36
ShowWindowAsync(instance.MainWindowHandle, SW_RESTORE);
37
//前置窗口
38
SetForegroundWindow(instance.MainWindowHandle);
39
}
40![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
[DllImport("User32.dll")]
42
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
43
[DllImport("User32.dll")]
44
private static extern bool SetForegroundWindow(IntPtr hWnd);
45
[DllImport("user32.dll")]
46
private static extern bool IsIconic(IntPtr hWnd);
47
private const int SW_RESTORE = 9;
48
}
49
public class ProcessID : MarshalByRefObject {
50
private int _pID;
51
public int PID {
52
get { return _pID; }
53
}
54
public ProcessID() {
55
_pID = Process.GetCurrentProcess().Id;
56
}
57
}
58
}
其中进程间通讯的代码来自与《利用IPC通道进行进程间通信(C#)》。这方面的知识原来没有学过,也许还有更方便的办法。![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
20
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
22
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
23
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
24
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
26
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
28
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
30
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
32
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
33
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
34
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
36
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
38
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
40
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
42
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
44
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
45
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
46
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
48
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
49
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
50
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
51
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
52
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
53
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
54
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
55
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
56
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
57
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
58
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
这里面只涉及了很简单的情况,即单个窗口的情况。没有考虑MDI程序,在主窗口里面打开的情况。