【问题标题】:How Can I Get My File Association to Open Multiple Files in a Single Program Instance?如何让我的文件关联在单个程序实例中打开多个文件?
【发布时间】:2011-04-06 01:48:33
【问题描述】:

我在注册表中为我的程序as Windows requires 设置了文件扩展名。

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

"C:\MyProgramPath\MyProgram.exe" "%1" 

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

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

【问题讨论】:

    标签: windows shell registry associations


    【解决方案1】:

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

    现在,如果您只需要一个应用程序实例,您需要这样做:

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

    一种非常简单的方法

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

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

    详情

    由于这是一个相当普遍的问题,因此之前已经处理过。例如,请参阅this Delphi-specific article

    【讨论】:

    • 不幸的是,将它构建到我的程序中总是会阻止多个实例。但这不是我想要的。如果单击文件 A,我希望在实例 1 中使用它。如果然后单击文件 B,那么我希望在实例 2 中使用它。但是,如果在同一次单击中同时单击 A 和 B,那么它们将是 2 个参数立即传递给程序,我希望它们都在一个实例中打开。我为什么要那个?这样它与从命令行使用 2 个参数运行我的程序,或将 2 个文件拖放到我的程序中具有相同的效果。谢谢,但这对我没有帮助。
    • @Ikessler:我明白了。我不明白你的意思是这样。也许你应该在你的问题中写下这个?
    • 很抱歉之前没有提到它,但直到你给出答案我才意识到它是相关的。非常感谢您花时间编写详细的答案。
    【解决方案2】:

    您可以在使用DDE 时。 Delphi 中的示例参见http://cc.embarcadero.com/Item/17787

    编辑:

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

    【讨论】:

    • 在我链接到的 MSDN 页面上,它显示“注意:不推荐使用 DDE 方法;请改用 DropTarget 方法。”我无法弄清楚如何在 Delphi 中设置 IDropTarget。我还是应该选择 DDE 吗?
    • 似乎 IDropHandler 是要走的路。现在我要做的就是弄清楚如何做到这一点。我已经问过另一个问题以寻求帮助:stackoverflow.com/questions/3613333/…
    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多