Implement Explorer ContextMenu and pass multiple files to one program instance

后端 未结 3 882
别跟我提以往
别跟我提以往 2020-12-30 05:25

Situation

I have a 3rd party GUI application that accepts multiple files via CLI, for example:

MyProgram.exe \"file1\" \         


        
3条回答
  •  感动是毒
    2020-12-30 05:42

    EDIT: I discarded this solution because I've discovered that this approach has very bad disadvantages.


    So, this is how it looks in VB.Net this easy approach (thanks for @Roy van der Velde)

    It stores the filepaths in a string builder in this format:

    "File1" "File2 "File3"
    

    After an inactivity time (using a Timer), the filepath arguments are passed to the specified application, and that's all.

    The code is rehusable and customizable :)

    It should be marked as single-instance if VB.Net, if C# then use a Mutex or... I don't know how to.

    Main Form Class:

    Public Class Main
    
        Public Sub New()
    
            ' This call is required by the designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            Me.Size = New Size(0, 0)
            Me.Hide()
            Me.SuspendLayout()
    
        End Sub
    
    End Class
    

    Application Events class:

    #Region " Option Statements "
    
    Option Strict On
    Option Explicit On
    Option Infer Off
    
    #End Region
    
    #Region " Imports "
    
    Imports Microsoft.VisualBasic.ApplicationServices
    Imports System.IO
    Imports System.Text
    
    #End Region
    
    Namespace My
    
        ''' 
        ''' Class MyApplication.
        ''' 
        Partial Friend Class MyApplication
    
    #Region " Properties "
    
            ''' 
            ''' Gets the application path to pass the filepaths as a single-line argument.
            ''' 
            ''' The application path.
            Private ReadOnly Property AppPath As String
                Get
                    Return Path.Combine(My.Application.Info.DirectoryPath, "MP3GainGUI.exe")
                End Get
            End Property
    
            ''' 
            ''' Gets the inactivity timeout, in milliseconds.
            ''' 
            ''' The inactivity timeout, in milliseconds.
            Private ReadOnly Property TimeOut As Integer
                Get
                    Return 750
                End Get
            End Property
    
            ''' 
            ''' Gets the catched filepaths.
            ''' 
            ''' The catched filepaths.
            Private ReadOnly Property FilePaths As String
                Get
                    Return Me.filePathsSB.ToString
                End Get
            End Property
    
    #End Region
    
    #Region " Misc. Objects "
    
            ''' 
            ''' Stores the catched filepaths.
            ''' 
            Private filePathsSB As StringBuilder
    
            ''' 
            ''' Keeps track of the current filepath count.
            ''' 
            Private filePathCount As Integer
    
            ''' 
            ''' Timer that determines whether the app is inactive.
            ''' 
            Private WithEvents inactivityTimer As New Timer With
                {
                    .Enabled = False,
                    .Interval = Me.TimeOut
                }
    
    #End Region
    
    #Region " Event Handlers "
    
            ''' 
            ''' Handles the Startup event of the application.
            ''' 
            ''' The source of the event.
            ''' The  instance containing the event data.
            Private Sub Me_Startup(ByVal sender As Object, ByVal e As StartupEventArgs) _
            Handles Me.Startup
    
                Select Case e.CommandLine.Count
    
                    Case 0 ' Terminate the application.
                        e.Cancel = True
    
                    Case Else ' Add the filepath argument and keep listen to next possible arguments.
                        Me.filePathsSB = New StringBuilder
                        Me.filePathsSB.AppendFormat("""{0}"" ", e.CommandLine.Item(0))
                        Me.filePathCount += 1
    
                        With Me.inactivityTimer
                            .Tag = Me.filePathCount
                            .Enabled = True
                            .Start()
                        End With
    
                End Select
    
            End Sub
    
            ''' 
            ''' Handles the StartupNextInstance event of the application.
            ''' 
            ''' The source of the event.
            ''' The  instance containing the event data.
            Private Sub Me_StartupNextInstance(ByVal sender As Object, ByVal e As StartupNextInstanceEventArgs) _
            Handles Me.StartupNextInstance
    
                Select Case e.CommandLine.Count
    
                    Case 0 ' Terminate the timer and run the application.
                        Me.TerminateTimer()
    
                    Case Else ' Add the filepath argument and keep listen to next possible arguments.
                        Me.filePathsSB.AppendFormat("""{0}"" ", e.CommandLine.Item(0))
                        Me.filePathCount += 1
    
                End Select
    
            End Sub
    
            ''' 
            ''' Handles the Tick event of the InactivityTimer control.
            ''' 
            ''' The source of the event.
            ''' The  instance containing the event data.
            Private Sub InactivityTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) _
            Handles inactivityTimer.Tick
    
                Dim tmr As Timer = DirectCast(sender, Timer)
    
                If DirectCast(tmr.Tag, Integer) = Me.filePathCount Then
                    Me.TerminateTimer()
    
                Else
                    tmr.Tag = Me.filePathCount
    
                End If
    
            End Sub
    
    #End Region
    
    #Region " Methods "
    
            ''' 
            ''' Terminates the inactivity timer and runs the application.
            ''' 
            Private Sub TerminateTimer()
    
                Me.inactivityTimer.Enabled = False
                Me.inactivityTimer.Stop()
                Me.RunApplication()
    
            End Sub
    
            ''' 
            ''' Runs the default application passing all the filepaths as a single-line argument.
            ''' 
            Private Sub RunApplication()
    
    #If DEBUG Then
                Debug.WriteLine(Me.FilePaths)
    #End If
                Try
                    Process.Start(Me.AppPath, Me.FilePaths)
    
                Catch ex As FileNotFoundException
                    ' Do Something?
                End Try
    
                ' Terminate the application.
                MyBase.MainForm.Close()
    
            End Sub
    
    #End Region
    
        End Class
    
    End Namespace
    

提交回复
热议问题