2

我正在开发一个桌面应用程序(C# 4.0 Winforms),其中一个要求是程序可以多次打开。但是,我不希望用户能够多次打开给定文档(可能会发生坏事)。

基本上我希望它的功能类似于 MS Word(至少是较新版本),如果您尝试打开一个已经打开的文档,它会将您带到已经打开该文档的程序实例。

我大部分时间都在做 Web 开发,所以可能有一些我不知道的简单解决方案。

所以我真的有两种不同的需求。

1) 防止文件被打开超过一次 2) 如果他们试图再次打开它,将实例带到前台。

我可以想到几种方法来处理#1,但我很好奇其他人是如何解决这个问题的。

实际上,我真的不知道从哪里开始尝试让#2 工作,而无需制作一些保持打开状态并创建子程序的主表单/流程。IE 创建了另一个窗体,它实际控制当前程序主窗体的打开和关闭,因此它更像是一种“选项卡式”体验,而不是实际的多窗口体验。更像是老式的 MDI(仍然会留下问题 #1)。

此处的任何帮助(要阅读的站点、要查看的名称空间等)将不胜感激。

编辑 -我看到这已被标记为重复,并且“重复”位于页面顶部。我的要求之一是程序必须能够多次打开。你们还看帖子吗?其他人可以进来投票重新讨论这个问题吗?

进一步编辑 -我采用了 Mutex 的想法,以防止程序多次打开同一个文档。我从来没有找到一种简单的方法来确定程序的哪个实例打开了文档并将其放在前面,所以我现在放弃了,只是弹出一个消息框告诉他们它已经打开了。命名管道似乎有点矫枉过正,因为它不完全是我想要做的,并且会涉及很多开销(而且 WCF 不是世界上最简单的事情),所以任何进一步的帮助将不胜感激。

4

2 回答 2

1

您在询问互斥锁。在 Windows 中,您可以创建一个 MUTEX(互斥标志),因此即使进程的第二个实例打开,它也会尝试创建互斥体然后失败。互斥锁是用于此目的的操作系统范围的全局变量(有点),用于 IPC/协调。

另一种方法是这样 - 创建一个具有嵌入文档名称的类名称(在 windows API 中的类而不是在 C# 或 C++ 中的类),并使用 FindWindow() 函数首先查看这样的窗口是否已经打开。然后您可以 SendMessage(HWND) 向该窗口发送一条消息以将其置于最前面,因此如果用户在资源管理器“myfile.doc”中单击并且它已经打开 - 您只需将其置于最前面。要查看的 API(从我的大脑 ram 中,我如何记住这些东西?):

 CreateMutex() / OpenMutex()
 FindWindow() / CreateWindow()
 SendMessage() / PostMessage()
 ShowWindow()/ SetWindowPosition()/BringWinToTop()
于 2012-12-30T01:17:58.827 回答
1

我怀疑有很多方法可以解决这个问题,但这是我的处理方法:

只有一个应用程序实例,并在应用程序的新窗口中打开每个请求的文档。

这将需要一些协调,因为随后打开的文档将导致创建一个新实例,但您可以设置应用程序的第一个实例创建并检查后续实例的进程间通信机制(例如命名管道)。

如果他们发现 IPC 存在,他们将请求的文件名传递给第一个应用程序实例(打开指定的文件),然后终止。

这是微软关于命名管道使用的一篇好文章:如何:使用命名管道进行网络进程间通信

于 2012-12-30T01:23:10.200 回答