4

在玩弄了一个新的 Windows 窗体项目后,我发现当您将文件类型与 Windows 中的可执行文件相关联时,您可以使用args[0]from找到启动应用程序的文件的文件路径static void Main(string[] args)

如果您的应用程序已经打开,是否可以在双击文件时在您的应用程序上启动事件?(显然Main(string[] args)不会被触发)。

我试图复制的具有行为的应用程序示例:

  1. 用户打开 GIMP(在 Windows 中)
  2. 用户打开资源管理器并右键单击 .png 文件
  3. 用户选择使用 GIMP 打开
  4. GIMP 不会创建新的 GIMP 应用程序实例,而是在已打开的 GIMP 实例内的新窗口中打开图片。

在这种情况下,GIMP 是否使用多个应用程序来接受文件关联“打开”的文件?或者是否可以使用单个应用程序“实例”来做到这一点。

我在这方面遇到了麻烦,因为我的大多数搜索都倾向于让我以 Windows 用户的身份进行文件关联(即“如何将 .xls 文件与 excel 相关联”文章)。

4

4 回答 4

4

有多种选择,但没有一个是免费的。

  1. 您的程序Main()可以检测到另一个副本已经在运行,并通过您确定的某种方式将文件名传递给已经运行的副本。
  2. 您的程序可以注册为 DDE 服务器并请求通过 DDE 执行后续打开。这是 1990 年代的一种老式技术,通常不推荐用于新程序。
  3. 您可以为您的应用程序注册一个自定义放置目标,并让放置目标将文件名传递给已经运行的副本。此机制采用 shell 扩展的形式,因此由于 CLR 注入问题而不适用于 C#。

鉴于您的限制,选项 (1) 似乎是最佳选择。

于 2011-10-17T19:15:38.163 回答
3

Raymond 当然是对的,但是如果您正在寻求有关选项 (1) 实施的帮助,您可能应该查看创建单实例应用程序的正确方法是什么?.NET 4 单个应用程序实例切换到同一应用程序的其他实例

您会注意到检测应用程序非常容易(使用互斥锁)。带来另一个应用程序并向其发送文件名可能更具挑战性。

之前链接的问题的答案中提供了三个基本解决方案

  1. 用于PostMessage向第一个实例发送消息。这种用途HWND_BROADCAST可能会产生意想不到的后果。

  2. 使用Microsoft.VisualBasic.ApplicationServices.ApplicationBase当然,对VisualBasic的引用 会给一些 C# 开发人员带来麻烦。

  3. 使用FindWindow依赖于 Windows 名称的。

还值得注意的是,如果您希望现有应用程序位于前面,则需要特别小心,因为设置前景只能放弃而不能采取。看前台激活权限就像爱情:不能偷,必须给你AllowSetForegroundWindowSetForegroundWindow

于 2011-10-17T20:37:50.840 回答
0

Microsoft 为 Visual Basic .Net 创建了此功能,C# 也可以使用它。

有关 C# 中的简单示例,请参阅以下帖子:

http://www.openwinforms.com/single_instance_application.html

于 2011-10-17T20:11:34.213 回答
0

这种方法最适合我:Enforcing Single Instance WPF Applications。特别是,它用于传递参数的解决方案也适用于仅通知图标的应用程序。

于 2013-05-30T06:22:25.763 回答