如何将命令行参数传递给运行中的第一个.net单实例应用程序实例?

2026-04-29 06:592阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1475个文字,预计阅读时间需要6分钟。

如何将命令行参数传递给运行中的第一个.net单实例应用程序实例?

当用户使用Registry快捷键单击+Windows资源管理器中的文件时,我已经实现了上下文菜单。文件地址将被作为命令行参数传递给应用程序。已解析无误。要实现类似添加到Windows Media Player播放的功能,您可以考虑以下步骤:

1. 在上下文菜单中添加一个新选项,例如添加到Windows Media Player。

2.当用户选择此选项时,编写一个脚本或程序,它将文件路径作为参数传递给Windows Media Player。

3.使用Windows Media Player的命令行接口(如wmplayer.exe)来实现这一功能。

以下是一个简单的示例脚本,用于将文件添加到Windows Media Player播放列表:

batch

@echo offset file=%~1start wmplayer.exe /play /add %file%

将此脚本保存为`.bat`文件,例如`add_to_wmp.bat`,然后在上下文菜单中使用它。您可以通过编程方式将此脚本与上下文菜单的选项关联起来。

当用户使用Registry右键单击 Windows资源管理器中的文件时,我已经实现了上下文菜单.文件地址将作为命令行传递给应用程序.解析它没问题.

我该如何实现类似于“添加到Windows Media Player播放列表”?它不会打开应用程序的另一个实例,但在同一个打开的窗口上工作并将其添加到列表中?

有两种方法可以执行此操作,具体取决于应用的启动方式.

方法1:使用VB App Framework和MainForm

这是最简单的,因为您只需要为Application事件添加一些代码.首先,在主窗体中添加一个方法,以便从应用的后续实例接收新参数:

Public Class MyMainForm ' note the class name of the form ... Public Sub NewArgumentsReceived(args As String()) ' e.g. add them to a list box If args.Length > 0 Then lbArgs.Items.AddRange(args) End If End Sub

下一个:

>打开项目属性
>选中“Make Single Instance”选项
>在底部,单击“查看应用程序事件”
>这将像任何其他窗口一样打开一个新的代码窗口;在左下角选择MyApplication Events;和正确的StartupNextInstance.

在这里,我们找到主窗体并将命令行参数发送到我们创建的方法:

Private Sub MyApplication_StartupNextInstance(sender As Object, e As ApplicationServices.StartupNextInstanceEventArgs) _ Handles Me.StartupNextInstance Dim f = Application.MainForm ' use YOUR actual form class name: If f.GetType Is GetType(MyMainForm) Then CType(f, MyMainForm).NewArgumentsReceived(e.CommandLine.ToArray) End If End Sub

注意:不要尝试从Application.OpenForms中删除主窗体.有几次我没有在集合中找到一个开放的表单,所以我放弃了依赖它. Application.MainForm也更简单.

就是这样 – 当一个新实例运行时,它的命令行args应该传递给表单并显示在列表框中(或者处理,但是你的方法看起来合适).

方法2:从Sub Main开始

这更复杂,因为从Sub Main启动应用程序意味着不使用VB Application Framework,它提供了StartupNextInstance事件.解决方案是将WindowsFormsApplicationBase子类化以提供所需的功能.

首先,为主窗体提供一个有意义的名称,并添加类似NewArgumentsReceived(args As String())的内容.

对于那些不知道的人,这里是如何从Sub Main()启动您的应用程序:

>将名为“Program”的模块添加到您的应用程序中
>向其中添加Public Sub Main().
>转到项目 – >属性 – >应用
>取消选中启用应用程序框架
>选择新的“Sub Main”作为启动对象

如何将命令行参数传递给运行中的第一个.net单实例应用程序实例?

该模块实际上可以命名为任何东西,Program是VS用于C#应用程序的约定. Sub Main的代码将在我们创建类之后.以下大部分内容源自旧的MSDN文章或博客或其他内容.

Imports Microsoft.VisualBasic.ApplicationServices Imports System.Collections.ObjectModel Public Class SingleInstanceApp ' this is My.Application Inherits WindowsFormsApplicationBase Public Sub New(mode As AuthenticationMode) MyBase.New(mode) InitializeApp() End Sub Public Sub New() InitializeApp() End Sub ' standard startup procedures we want to implement Protected Overridable Sub InitializeApp() Me.IsSingleInstance = True Me.EnableVisualStyles = True End Sub ' ie Application.Run(frm): Public Overloads Sub Run(frm As Form) ' set mainform to be used as message pump Me.MainForm = frm ' pass the commandline Me.Run(Me.CommandLineArgs) End Sub Private Overloads Sub Run(args As ReadOnlyCollection(Of String)) ' convert RO collection to simple array ' these will be handled by Sub Main for the First instance ' and in the StartupNextInstance handler for the others Me.Run(myArgs.ToArray) End Sub ' optional: save settings on exit Protected Overrides Sub OnShutdown() If My.Settings.Properties.Count > 0 Then My.Settings.Save() End If MyBase.OnShutdown() End Sub End Class

请注意,App Framework可以为我们做的三件主要事情(“启用XP样式”,“制作单个实例”和“退出时保存设置”)都被考虑在内.现在,Sub Main的一些修改:

Imports Microsoft.VisualBasic.ApplicationServices Imports System.Collections.ObjectModel Module Program ' this app's main form Friend myForm As MyMainForm Public Sub Main(args As String()) ' create app object hardwired to SingleInstance Dim app As New SingleInstanceApp() ' add a handler for when a second instance tries to start ' (magic happens there) AddHandler app.StartupNextInstance, AddressOf StartupNextInstance myForm = New MyMainForm ' process command line args here for the first instance ' calling the method you added to the form: myForm.NewArgumentsReceived(args) ' start app app.Run(myForm) End Sub ' This is invoked when subsequent instances try to start. ' grab and process their command line Private Sub StartupNextInstance(sender As Object, e As StartupNextInstanceEventArgs) ' ToDo: Process the command line provided in e.CommandLine. myForm.NewArgumentsReceived(e.CommandLine.ToArray) End Sub End Module

SingleInstanceApp类可以与任何Sub Main样式应用程序一起使用,并且该方法中的代码主要是复制粘贴样板事件,除了可能是NewArgumentsReceived方法的表单引用和实际名称.

测试

编译应用程序,然后使用命令窗口,向应用程序发送一些命令行参数.我用了:

C:\Temp>singleinstance “First Inst” apple bats cats

这会正常启动应用程序,并显示参数.然后:

C:\Temp>singleinstance “Next Inst” ziggy zoey zacky
C:\Temp>singleinstance “Last Inst” 111 222 3333

使用哪种方法无关紧要 – 它们的工作原理相同.结果:

请注意,根据安全设置,防火墙可能会使用任一方法连接到其他计算机来请求应用程序的权限.这是实例如何发送或侦听来自其他人的参数的结果.至少在我的情况下,我可以拒绝连接的许可,一切仍然正常.

本文共计1475个文字,预计阅读时间需要6分钟。

如何将命令行参数传递给运行中的第一个.net单实例应用程序实例?

当用户使用Registry快捷键单击+Windows资源管理器中的文件时,我已经实现了上下文菜单。文件地址将被作为命令行参数传递给应用程序。已解析无误。要实现类似添加到Windows Media Player播放的功能,您可以考虑以下步骤:

1. 在上下文菜单中添加一个新选项,例如添加到Windows Media Player。

2.当用户选择此选项时,编写一个脚本或程序,它将文件路径作为参数传递给Windows Media Player。

3.使用Windows Media Player的命令行接口(如wmplayer.exe)来实现这一功能。

以下是一个简单的示例脚本,用于将文件添加到Windows Media Player播放列表:

batch

@echo offset file=%~1start wmplayer.exe /play /add %file%

将此脚本保存为`.bat`文件,例如`add_to_wmp.bat`,然后在上下文菜单中使用它。您可以通过编程方式将此脚本与上下文菜单的选项关联起来。

当用户使用Registry右键单击 Windows资源管理器中的文件时,我已经实现了上下文菜单.文件地址将作为命令行传递给应用程序.解析它没问题.

我该如何实现类似于“添加到Windows Media Player播放列表”?它不会打开应用程序的另一个实例,但在同一个打开的窗口上工作并将其添加到列表中?

有两种方法可以执行此操作,具体取决于应用的启动方式.

方法1:使用VB App Framework和MainForm

这是最简单的,因为您只需要为Application事件添加一些代码.首先,在主窗体中添加一个方法,以便从应用的后续实例接收新参数:

Public Class MyMainForm ' note the class name of the form ... Public Sub NewArgumentsReceived(args As String()) ' e.g. add them to a list box If args.Length > 0 Then lbArgs.Items.AddRange(args) End If End Sub

下一个:

>打开项目属性
>选中“Make Single Instance”选项
>在底部,单击“查看应用程序事件”
>这将像任何其他窗口一样打开一个新的代码窗口;在左下角选择MyApplication Events;和正确的StartupNextInstance.

在这里,我们找到主窗体并将命令行参数发送到我们创建的方法:

Private Sub MyApplication_StartupNextInstance(sender As Object, e As ApplicationServices.StartupNextInstanceEventArgs) _ Handles Me.StartupNextInstance Dim f = Application.MainForm ' use YOUR actual form class name: If f.GetType Is GetType(MyMainForm) Then CType(f, MyMainForm).NewArgumentsReceived(e.CommandLine.ToArray) End If End Sub

注意:不要尝试从Application.OpenForms中删除主窗体.有几次我没有在集合中找到一个开放的表单,所以我放弃了依赖它. Application.MainForm也更简单.

就是这样 – 当一个新实例运行时,它的命令行args应该传递给表单并显示在列表框中(或者处理,但是你的方法看起来合适).

方法2:从Sub Main开始

这更复杂,因为从Sub Main启动应用程序意味着不使用VB Application Framework,它提供了StartupNextInstance事件.解决方案是将WindowsFormsApplicationBase子类化以提供所需的功能.

首先,为主窗体提供一个有意义的名称,并添加类似NewArgumentsReceived(args As String())的内容.

对于那些不知道的人,这里是如何从Sub Main()启动您的应用程序:

>将名为“Program”的模块添加到您的应用程序中
>向其中添加Public Sub Main().
>转到项目 – >属性 – >应用
>取消选中启用应用程序框架
>选择新的“Sub Main”作为启动对象

如何将命令行参数传递给运行中的第一个.net单实例应用程序实例?

该模块实际上可以命名为任何东西,Program是VS用于C#应用程序的约定. Sub Main的代码将在我们创建类之后.以下大部分内容源自旧的MSDN文章或博客或其他内容.

Imports Microsoft.VisualBasic.ApplicationServices Imports System.Collections.ObjectModel Public Class SingleInstanceApp ' this is My.Application Inherits WindowsFormsApplicationBase Public Sub New(mode As AuthenticationMode) MyBase.New(mode) InitializeApp() End Sub Public Sub New() InitializeApp() End Sub ' standard startup procedures we want to implement Protected Overridable Sub InitializeApp() Me.IsSingleInstance = True Me.EnableVisualStyles = True End Sub ' ie Application.Run(frm): Public Overloads Sub Run(frm As Form) ' set mainform to be used as message pump Me.MainForm = frm ' pass the commandline Me.Run(Me.CommandLineArgs) End Sub Private Overloads Sub Run(args As ReadOnlyCollection(Of String)) ' convert RO collection to simple array ' these will be handled by Sub Main for the First instance ' and in the StartupNextInstance handler for the others Me.Run(myArgs.ToArray) End Sub ' optional: save settings on exit Protected Overrides Sub OnShutdown() If My.Settings.Properties.Count > 0 Then My.Settings.Save() End If MyBase.OnShutdown() End Sub End Class

请注意,App Framework可以为我们做的三件主要事情(“启用XP样式”,“制作单个实例”和“退出时保存设置”)都被考虑在内.现在,Sub Main的一些修改:

Imports Microsoft.VisualBasic.ApplicationServices Imports System.Collections.ObjectModel Module Program ' this app's main form Friend myForm As MyMainForm Public Sub Main(args As String()) ' create app object hardwired to SingleInstance Dim app As New SingleInstanceApp() ' add a handler for when a second instance tries to start ' (magic happens there) AddHandler app.StartupNextInstance, AddressOf StartupNextInstance myForm = New MyMainForm ' process command line args here for the first instance ' calling the method you added to the form: myForm.NewArgumentsReceived(args) ' start app app.Run(myForm) End Sub ' This is invoked when subsequent instances try to start. ' grab and process their command line Private Sub StartupNextInstance(sender As Object, e As StartupNextInstanceEventArgs) ' ToDo: Process the command line provided in e.CommandLine. myForm.NewArgumentsReceived(e.CommandLine.ToArray) End Sub End Module

SingleInstanceApp类可以与任何Sub Main样式应用程序一起使用,并且该方法中的代码主要是复制粘贴样板事件,除了可能是NewArgumentsReceived方法的表单引用和实际名称.

测试

编译应用程序,然后使用命令窗口,向应用程序发送一些命令行参数.我用了:

C:\Temp>singleinstance “First Inst” apple bats cats

这会正常启动应用程序,并显示参数.然后:

C:\Temp>singleinstance “Next Inst” ziggy zoey zacky
C:\Temp>singleinstance “Last Inst” 111 222 3333

使用哪种方法无关紧要 – 它们的工作原理相同.结果:

请注意,根据安全设置,防火墙可能会使用任一方法连接到其他计算机来请求应用程序的权限.这是实例如何发送或侦听来自其他人的参数的结果.至少在我的情况下,我可以拒绝连接的许可,一切仍然正常.