如何让我的文件关联在单个程序实例中打开多个文件?

lke*_*ler 6 windows registry shell associations

我已根据Windows的要求在注册表中为我的程序设置了文件扩展名.

在注册表中,在shell/open/command下,我有:

"C:\MyProgramPath\MyProgram.exe" "%1" 
Run Code Online (Sandbox Code Playgroud)

这对我来说很好.当有人点击与我的应用程序关联的一个或多个文件时,我的应用程序正确打开文件,但每个文件都在一个单独的程序实例中打开.

有什么方法可以做到这一点并打开一个程序实例中的所有文件?

And*_*and 5

这是一个相当普遍的问题,它实际上与 Windows 文件扩展名无关。当您双击程序自定义类型的文件时,Windows 将启动关联的应用程序MyProgram.exe并将文件名%1作为命令行参数传递。

现在,如果您只想要应用程序的单个实例,则需要执行以下操作:

  1. 当您的程序 ( MyProgram.exe) 启动时,它应该检查是否已经有一个正在运行的实例。
  2. 如果有以前的实例,则新实例MyProgram.exe应向旧实例发送一条消息(某种类型,不一定是 Windows 消息),告诉它打开文件%1
  3. 新实例现在应该自行终止。

一个非常简单的方法

有几种方法可以实现这一点。最简单的方法之一是在每次应用程序启动时设置一个注册表项/值,并在应用程序存在时将其删除。然后,当您的应用程序(的新实例)启动时,在设置此键/值之前,它应该检查它是否已经设置。如果是,请按照上述步骤 (2) 和 (3) 进行操作。这可能不是最稳定的方法(实际上这是一个非常糟糕的主意,因为如果应用程序异常存在,您无法保证它会删除键/值),但它会给您基本的想法。其他可能更好的方法包括FindWindow使用互斥锁,甚至更好。

第二步可能通过发送windows消息(可能WM_COPYDATA),或者通过设置注册表值,或者,通过写一个文件,或者…… 不同进程之间的通信方式有很多种。

细节

由于这是一个相当普遍的问题,因此之前已经处理过。例如,请参阅这篇特定Delphi 的文章

  • 不幸的是,将它构建到我的程序中总是会阻止多个实例。但这不是我想要的。如果单击文件 A,我希望在实例 1 中使用它。如果然后单击文件 B,那么我希望在实例 2 中使用它。但是,如果在同一次单击中同时单击了 A 和 B,则它们将是 2 个参数立即传递给程序,我希望它们都在一个实例中打开。为什么我想要那个?这样它就具有与从带有 2 个参数的命令行运行我的程序或将 2 个文件拖放到我的程序中的效果相同的效果。谢谢,但这对我没有帮助。 (2认同)

Lar*_*ens 1

使用DDE时可以。有关 Delphi 中的示例,请参阅http://cc.embarcadero.com/Item/17787 。

编辑:

您提供的链接讨论了另一种方法:使用 IDropTarget。这可能更适合您已经运行的拖放功能。