如何通过文件关联执行已启动应用程序的事件?

发布于 2024-12-10 16:19:52 字数 559 浏览 0 评论 0原文

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

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

我尝试复制的应用程序行为示例:

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

在这种情况下,GIMP 是否使用多个应用程序来接受通过文件关联“打开”的文件?或者是否可以使用单个应用程序“实例”来完成此操作。

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

After playing around with a new Windows Form project, I discovered that when you associate a file type with an executable in Windows, you can find the file path of the file that launched the application using args[0] from static void Main(string[] args)

Is it possible to launch an event on your application when you double click a file if your application is already open? (As obviously Main(string[] args) won't be triggered).

Example of an application with behavior I am attempting to replicate:

  1. User Opens GIMP(in Windows)
  2. User opens explorer and right clicks a .png file
  3. User selects open with GIMP
  4. Instead of creating a new application instance of GIMP, GIMP opens the picture in a new window within the instance of GIMP that was already opened.

In this case is GIMP employing multiple applications to accept files "opened" with file association? Or is it possible to do it with a single application "instance".

I'm having trouble with this as most of my searches tend to lead me towards file association as a Windows user (i.e. "How to associate .xls files with excel" articles).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小忆控 2024-12-17 16:19:52

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

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

考虑到您的限制,选项 (1) 似乎是最佳选择。

There are a variety of options, but none of them come for free.

  1. Your program's Main() can detect that there is another copy already running and hand the file name off to the already-running copy by some means you determine.
  2. Your program can register as a DDE server and request that subsequent opens be performed via DDE. This is an old-fashioned technique from the 1990's that is generally not recommended for new programs.
  3. You can register a custom drop target for your application, and have the drop target hand the file name to the already-running copy. This mechanism takes the form of a shell extension, and therefore is not suitable for C# due to CLR injection issues.

Given your constraints, option (1) appears to be the best option.

夏花。依旧 2024-12-17 16:19:52

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

您会注意到检测应用程序非常简单(使用互斥锁)。引入其他应用程序并向其发送文件名可能更具挑战性。

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

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

  2. 使用 Microsoft.VisualBasic.ApplicationServices.ApplicationBase< /a> 当然,对 VisualBasic 的引用会让一些 C# 开发人员感到不安。

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

还值得注意的是,如果您希望现有应用程序位于前面,则需要特别小心,因为设置前景只能被放弃而不能被夺走。请参阅 前台激活权限就像爱:你不能偷了它,它必须给你AllowSetForegroundWindow设置前景窗口

Raymond is right of course, but if you're looking for help with the implmentation of option (1) you should probably look at What is the correct way to create a single instance application? and .NET 4 single application instance and Switch to other instance of same application

You'll notice that detecting the application is pretty easy (use a mutex). Bringing the other application and sending it a filename can be more challenging.

There are three basic solutions presented in the answers to the previously linked questions

  1. Use PostMessage to send a message to 1st instance. This uses HWND_BROADCAST which can have untended consequences.

  2. Use Microsoft.VisualBasic.ApplicationServices.ApplicationBase Of course a reference to VisualBasic gives some C# devs the willies.

  3. Use FindWindow which relies on a Windows Name.

Its also worth noting that if you want the existing application to be in the front you'll need to take special care because setting the foreground can only be given away not taken. See Foreground activation permission is like love: You can't steal it, it has to be given to you and AllowSetForegroundWindow and SetForegroundWindow

风吹雪碎 2024-12-17 16:19:52

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

请参阅以下文章,了解 C# 中的简单示例:

http://www.openwinforms.com/single_instance_application.html< /a>

Microsoft created this functionality for Visual Basic .Net, and it can be used by C# too.

See the following post for a simple example in C#:

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

紅太極 2024-12-17 16:19:52

这种方法最适合我:强制执行单实例 WPF 应用程序
特别是,其传递参数的解决方案也适用于仅通知图标的应用程序。

This approach worked best for me: Enforcing Single Instance WPF Applications.
Especially, its solution for passing arguments also works in notify-icon only applications.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文