积极答复者
一个关于防止程序重复启动的问题

问题
-
目前已经能够检测到程序重复启动,但是我想当程序检测到被重复启动后之前已经启动的程序由hide状态变为show状态。
我检测重复进程使用的方式是检测进程列表,一旦有检测到重复进程就向本地127.0.0.1发送一个UDP数据包,然后后启动的就app.current.shutdown()。
App.cs:
AsyncCallback callBack = new AsyncCallback(receiveFile_RequestSendFile);
UdpClient uc2 = new UdpClient(7021);
uc2.BeginReceive(callBack, "1"); //当端口7021接收到数据包的时候执行回调函数
void receiveFile_RequestSendFile(IAsyncResult result)
{
if (SizeFlag == 0) //检测当前mainwindow状态是否为.hide()状态
{
Action action = new Action(delegate()
{
Thread.Sleep(5000);
this.MainWindow.Show();
this.MainWindow.Activate();
});
action.BeginInvoke(null, null);
}
}错误提示:调用线程无法访问此对象,因为另一个线程拥有该对象。请问是什么原因导致的?有什么好的解决方法么?
答案
-
WaitOne方法会阻塞线程,这应该是期待的一个特点:第一个进程并不知道第二个进程何时启动,所以它在WaitOne这里阻塞等待,类似于你原来方案里的监听过程,一旦阻塞通过了,那表明第二个进程被启动了,然后紧接着按排你的那个设置主窗口拥有焦点Action执行
这个方法的缺点是只能传送非常有限的信息,就一个信号而已;如果有更多信息需要在进程间交换,还是版主提到的命名管道的方式最为有效和方便;UDP端口适用于跨机器的进程交换,对于一台机器上进程间通信来说,它的代价高了些
共享文件的方式,我个人一直觉得这个方法用于进程通信有点尴尬,它需要使用磁盘外设,性能上会有个损失,不如用命名管道.共享文件我觉得更主要的目的是用于集群性质进程的持久化,比如工作流那的玩意的持久化.
嗯,这个可以试试,不知道WaitOne会不会影响到程序正常运行..
- 已建议为答案 Jie BaoModerator 2011年3月23日 6:28
- 已标记为答案 Jie BaoModerator 2011年3月28日 2:31
-
mutex 可以用,也可以到msdn里面查查mutex。
关于mutex,我保留意见,在比较差的机器上运行,这个东东就不太管用了,因为他自己也需要创建时间,你可以到网上找找资料。查找进程,这个方法比较快,我也是用这个。
第二个程序运行后,可以给第一个程序SendMessage,然后自己hidden
第一个程序通过hook接收消息,进行相关操作。
这篇文章可以帮到你,仔细看看,跟你的要求基本类似。
http://www.cnblogs.com/xiaokang088/archive/2011/02/23/1962503.html
- 已标记为答案 Jie BaoModerator 2011年3月28日 2:31
-
我已经找到解决方案了,就是使用进程查找配合FindWindow的方法,很好用,窗口hide之前我将句柄存储在配置文件中就可以了。谢谢xiaokang088、AceBear还有Bob版主的帮助!
- 已建议为答案 Sheldon _XiaoModerator 2011年3月29日 10:08
- 已标记为答案 Sheldon _XiaoModerator 2011年3月29日 10:08
全部回复
-
"我检测重复进程使用的方式是检测进程列表" 为什么不使用互斥对象来检测单例进程呢? 使用Mutex互斥对象可以实现这个功能,而且非常简单,只要这个进程创建了一个Mutex对象,这个进程如果还要启动并且创建这个互斥对象就会被阻止,然后就可以收到消息,通知说这个进程实例已经存在。这个内容在《WPF编程》一书中有提到,下面是一个例子,你可以试试:
public partial class App : Application { Mutex mutex; protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); bool isNew; mutex = new Mutex(true, "MyApplicationName", out isNew); if (!isNew) { MessageBox.Show("MyApplicationName is running!"); Shutdown(); } } }
“错误提示:调用线程无法访问此对象,因为另一个线程拥有该对象” 这样子调用方法去show Window:
void receiveFile_RequestSendFile(IAsyncResult result) { if (SizeFlag == 0) //检测当前mainwindow状态是否为.hide()状态 { Action action = new Action(delegate() { Thread.Sleep(5000); this.MainWindow.Show(); this.MainWindow.Activate(); }); this.MainWindow.Dispatcher.BeginInvoke(action, null); } }
使用 MainWindow的Dispatcher去调用委托,而不是在接收线程中调用 (接收线程异于UI线程)
Sincerely,
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
mutex = new Mutex(true, "MyApplicationName", out isNew);
isNew 会返回一个值 ,如果这个互斥对象已经存在,那么他返回 False.
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
你可以保留原来的网络通知的功能,在后来的进程中发送消息到之前的进程.
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
来个具体的例子吧 我来测试下 试试看有没有一个解决方案。
不过夸进程通信来说,方法有很多,我个人比较喜欢用 Remote .Net,开一个名字管道,发个消息;还有就是利用共享文件,也可以。
很久以前写的一个例子,是进程间通讯的:http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/MultiProcessCommunication.zip
Bob Bao [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
WaitOne方法会阻塞线程,这应该是期待的一个特点:第一个进程并不知道第二个进程何时启动,所以它在WaitOne这里阻塞等待,类似于你原来方案里的监听过程,一旦阻塞通过了,那表明第二个进程被启动了,然后紧接着按排你的那个设置主窗口拥有焦点Action执行
这个方法的缺点是只能传送非常有限的信息,就一个信号而已;如果有更多信息需要在进程间交换,还是版主提到的命名管道的方式最为有效和方便;UDP端口适用于跨机器的进程交换,对于一台机器上进程间通信来说,它的代价高了些
共享文件的方式,我个人一直觉得这个方法用于进程通信有点尴尬,它需要使用磁盘外设,性能上会有个损失,不如用命名管道.共享文件我觉得更主要的目的是用于集群性质进程的持久化,比如工作流那的玩意的持久化.
嗯,这个可以试试,不知道WaitOne会不会影响到程序正常运行..
- 已建议为答案 Jie BaoModerator 2011年3月23日 6:28
- 已标记为答案 Jie BaoModerator 2011年3月28日 2:31
-
mutex 可以用,也可以到msdn里面查查mutex。
关于mutex,我保留意见,在比较差的机器上运行,这个东东就不太管用了,因为他自己也需要创建时间,你可以到网上找找资料。查找进程,这个方法比较快,我也是用这个。
第二个程序运行后,可以给第一个程序SendMessage,然后自己hidden
第一个程序通过hook接收消息,进行相关操作。
这篇文章可以帮到你,仔细看看,跟你的要求基本类似。
http://www.cnblogs.com/xiaokang088/archive/2011/02/23/1962503.html
- 已标记为答案 Jie BaoModerator 2011年3月28日 2:31
-
我已经找到解决方案了,就是使用进程查找配合FindWindow的方法,很好用,窗口hide之前我将句柄存储在配置文件中就可以了。谢谢xiaokang088、AceBear还有Bob版主的帮助!
- 已建议为答案 Sheldon _XiaoModerator 2011年3月29日 10:08
- 已标记为答案 Sheldon _XiaoModerator 2011年3月29日 10:08
-
感谢你分享你的解决方案。
Sheldon _Xiao[MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.