Explorer, Rechtsklick, Eigenes Programm, Dateipfad übergeben

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von Volker Bunge.

    Explorer, Rechtsklick, Eigenes Programm, Dateipfad übergeben

    Hallo zusammen,

    möchte ein Programm schreiben, welches ich über das Explorer-Kontextmenü aufrufen kann.

    Den Eintrag in der Registry habe ich soweit hinbekommen, dass ich meinen Programmpfad dort eingetragen habe und das Programm wird auch gestartet.

    Nur wie bekomme ich jetzt den kpl. Dateipfad der Datei heraus, auf dem ich den Rechtsklick gemacht habe?

    Vielen Dank
    Volker
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Hallo mrMo,

    vielen Dank erst einmal für die noch so späte geschriebene Antwort.

    Habe mal den Sub Code so 1:1 direkt unter Public Class Form1 eingefügt und die letzte Console.WriteLine - Anweisung durch Msgbox ersetzt (damit ich was sehe).
    Danach habe ich per Rechtsklick im Explorer mein Programm geöffnet. Aber die Main Sub wurde dabei nicht aufgerufen.

    Dann habe ich die Main per Form_Load aufgerufen. Leider auch kein Erfolg.

    Habe jetzt mal eine neue Klasse Class1 erstellt und folgendes dort eingefügt

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Class1
    2. Public Shared Sub Main()
    3. Console.WriteLine()
    4. ' Invoke this sample with an arbitrary set of command line arguments.
    5. Dim arguments As String() = Environment.GetCommandLineArgs()
    6. Try
    7. Console.WriteLine("GetCommandLineArgs: {0}", String.Join(", ", arguments))
    8. MsgBox(arguments(0).ToString)
    9. MsgBox(arguments(1).ToString)
    10. MsgBox(arguments(2).ToString)
    11. Catch ex As Exception
    12. End Try
    13. End Sub
    14. End Class


    Der Aufruf erfolgt dann über das Form_Load Ereignis. Die Main-Sub wird jetzt auch angesprungen und die MsgBox liefert mit in der ersten Zeile den kpl. Pfad meiner Anwendung zurück.

    Könntest Du mir evtl. da noch mal genauer helfen? Wo muss was hin und wie muss ich ggf. das in mein Prg. einbinden?

    Vielen Dank

    Volker

    P.S. Class Sample ist doch wie Public Class Form1 zu sehen. Oder ist das eine Klasse die Sample heißt? Hoffe das ich die Lösung wie oben beschrieben schon selbst gefunden habe.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Volker Bunge“ ()

    Bau das mal in die Form Load Methode ein und schau ob im String Array dann die gesuchten Werte enthalten sind.

    Dim arguments As String() = Environment.GetCommandLineArgs()
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Zeig mal deinen Code und einen Screenshot vom Inhalt des Arrays.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Hier mal der Code im Form1 (unbearbeitet)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports Microsoft.Win32
    2. Public Class Form1
    3. 'Public Shared Sub Main()
    4. ' Console.WriteLine()
    5. ' ' Invoke this sample with an arbitrary set of command line arguments.
    6. ' Dim arguments As String() = Environment.GetCommandLineArgs()
    7. ' MsgBox("GetCommandLineArgs: {0}", String.Join(", ", arguments))
    8. 'End Sub
    9. ' Herkunft: VB 5/6 Code https://www.vbarchiv.net/tipps/details.php?id=116
    10. ' zunächst die benötigten API-Deklarationen
    11. 'Private Declare Function RegCreateKey Lib "advapi32.dll" Alias "RegCreateKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
    12. 'Private Declare Function RegSetValue Lib "advapi32.dll" Alias "RegSetValueA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal dwType As Long, ByVal lpData As String, ByVal cbData As Long) As Long
    13. ' strMenuText: Text, welcher im Kontextmenü erscheinen soll
    14. ' strAnwendung: Pfad + EXE-Dateiname der Anwendung
    15. ' Weitere Links
    16. ' https://docs.microsoft.com/de-de/previous-versions/technical-content/bb979360(v=msdn.10)?redirectedfrom=MSDN
    17. ' https://mycsharp.de/forum/threads/92375/eigene-anwendung-aus-windows-kontextmenue-aufrufen?page=1#forumpost-3664312
    18. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    19. ' Für den ersten Eintrag (Standard) mit ValueName = "" sein. Sonst legt er einen neuen an
    20. ' Call Registry_erstellen("*\shell\Datei mit Outlook verschicken", "", Application.ExecutablePath)
    21. 'Call Class1.Main()
    22. 'Console.WriteLine()
    23. ' Invoke this sample with an arbitrary set of command line arguments.
    24. Dim arguments As String() = Environment.GetCommandLineArgs()
    25. Try
    26. ' Console.WriteLine("GetCommandLineArgs: {0}", String.Join(", ", arguments))
    27. 'TextBox1.Text = "GetCommandLineArgs: {0}", String.Join(", ", arguments)
    28. MsgBox(arguments(0).ToString)
    29. MsgBox(arguments(1).ToString)
    30. MsgBox(arguments(2).ToString)
    31. Catch ex As Exception
    32. End Try
    33. End Sub
    34. Private Function Registry_lesen(KeyName As String, ValueName As String, Value As String) As String
    35. Return Registry.GetValue(KeyName, ValueName, Value)
    36. End Function
    37. Private Function Registry_schreiben(KeyName As String, ValueName As String, Value As String) As String
    38. Registry.SetValue(KeyName, ValueName, Value)
    39. '' https://www.vb-paradise.de/index.php/Thread/125664-Registry-SetValue-mit-Admin-Rechten/
    40. 'Dim myprocess As System.Diagnostics.Process = New System.Diagnostics.Process()
    41. 'With myprocess.StartInfo
    42. ' .FileName = ("reg.exe")
    43. ' .CreateNoWindow = False
    44. ' .Arguments = "add " + Chr(34) + KeyName + Chr(34) + " /v HiberbootEnabled /t REG_DWORD /d 0 /f"
    45. ' .RedirectStandardInput = False
    46. ' .RedirectStandardOutput = False
    47. ' .RedirectStandardError = False
    48. ' .UseShellExecute = True
    49. ' .Verb = "runas"
    50. 'End With
    51. 'myprocess.Start()
    52. End Function
    53. Private Function Registry_erstellen(KeyName As String, ValueName As String, Value As String) As String
    54. 'Registry.ClassesRoot.CreateSubKey(KeyName)
    55. 'Registry.ClassesRoot.OpenSubKey(ValueName)
    56. ''Registry_schreiben(KeyName, ValueName, Value)
    57. 'Registry.ClassesRoot.SetValue(ValueName, Value)
    58. ' Create a subkey named Test9999 under HKEY_CLASSES_ROOT.
    59. Dim test9999 As RegistryKey = Registry.ClassesRoot.CreateSubKey(KeyName)
    60. ' Create two subkeys under HKEY_CURRENT_USER\Test9999.
    61. 'test9999.CreateSubKey("TestName").Close()
    62. Dim testSettings As RegistryKey = test9999.CreateSubKey("Command")
    63. 'testSettings.DeleteValue(ValueName)
    64. ' Create data for the TestSettings subkey.
    65. 'testSettings.SetValue(ValueName, Value)
    66. Registry.SetValue("HKEY_CLASSES_ROOT\" & KeyName & "\Command", ValueName, Value)
    67. testSettings.Close()
    68. End Function
    69. Private Sub Btn_Lesen_Click(sender As Object, e As EventArgs) Handles Btn_Lesen.Click
    70. TBox_Ergebnis.Text = Registry_lesen(TBox_KeyName.Text, TBox_ValueName.Text, TBox_Value.Text)
    71. End Sub
    72. Private Sub Btn_Schreiben_Click(sender As Object, e As EventArgs) Handles Btn_Schreiben.Click
    73. Registry_schreiben(TBox_KeyName.Text, TBox_ValueName.Text, TBox_NeuerWert.Text)
    74. TBox_Value.Text = Registry_lesen(TBox_KeyName.Text, TBox_ValueName.Text, TBox_Value.Text)
    75. End Sub
    76. Private Sub Btn_Erstellen_Click(sender As Object, e As EventArgs) Handles Btn_Erstellen.Click
    77. ' Für den ersten Eintrag (Standard) mit ValueName = "" sein. Sonst legt er einen neuen an
    78. Call Registry_erstellen("*\shell\Datei mit Outlook verschicken", "", Application.ExecutablePath)
    79. End Sub
    80. End Class


    Wie meinst Du dass mit den Screenshot? Da ich zwar noch VB.Net offen habe (Projekt aber nicht gestartet habe) komme ich leider nach dem Rechtsklick an keine Stoppmarken oder an die Anzeige der Console ran (deshalb auch der Weg über die MsgBox. Die Zeile mit der Textbox1 funktioniert so leider auch nicht.
    @Volker Bunge Wo das steht ist völlig egal.
    Wichtig ist, wie Du das aufrufst.
    ====
    Meinst Du vielleicht so was:
    Die zu verwendende App auswählen => hier: SolutionExplorer.exe

    beim nächsten Mal wird sie vom System angeboten:

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Volker Bunge Du willst also PDF (zusätzlich) mit Deinem Programm verknüpfen?
    Dateierweiterung für eigenes Programm registrieren
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany,

    nicht nur PDF-Dateien sondern eigentlich alle.

    Habe gerade aber wohl meinen Fehler selbst gefunden bzw. durch Zufall entdeckt.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2. ' Für den ersten Eintrag (Standard) mit ValueName = "" sein.
    3. ' Prüfen, ob Programm schon registriert ist. Wenn nicht, dies nachholen
    4. ' "\\homeserver2\Nuetzliche Programmiertools\Visual Studio 2017\ProgImExplorerAufrufen\ProgImExplorerAufrufen\bin\Debug\ProgImExplorerAufrufen.exe" --share-file="%V"
    5. ' MsgBox(Registry_lesen("HKEY_CLASSES_ROOT\*\shell\Datei mit Outlook verschicken\Command", "", "") & vbCrLf & Chr(34) & Application.ExecutablePath & Chr(34) & " --share-file=" & Chr(34) & "%V" & Chr(34))
    6. If Registry_lesen("HKEY_CLASSES_ROOT\*\shell\Datei mit Outlook verschicken\Command", "", "") <> Chr(34) & Application.ExecutablePath & Chr(34) & " --share-file=" & Chr(34) & "%V" & Chr(34) Then
    7. Call Registry_erstellen(" *\ Shell() \ Datei mit Outlook verschicken", "", Application.ExecutablePath & " --share-file=" & Chr(34) & "%V" & Chr(34))
    8. ' Das Programm sollte über Autostart geladen werden. Wenn hier zu einem neuen Eintrag gekommen ist, dann hier das Programm verlassen
    9. MsgBox("Programm kann jetzt per Rechtsklick 'Datei mit Outlook verschicken' im Explorer aufgerufen werden.")
    10. Me.Close()
    11. Application.Exit()
    12. Exit Sub
    13. End If
    14. 'Call Class1.Main()
    15. 'Console.WriteLine()
    16. ' Invoke this sample with an arbitrary set of command line arguments.
    17. ' Rufen Sie dieses Beispiel mit einem beliebigen Satz von Befehlszeilenargumenten auf.
    18. Dim arguments As String() = Environment.GetCommandLineArgs()
    19. Try
    20. ' Console.WriteLine("GetCommandLineArgs: {0}", String.Join(", ", arguments))
    21. 'TextBox1.Text = "GetCommandLineArgs: {0}", String.Join(", ", arguments)
    22. MsgBox(arguments.Length)
    23. MsgBox(arguments(0).ToString)
    24. MsgBox(arguments(1).ToString)
    25. MsgBox(arguments(2).ToString)
    26. Catch ex As Exception
    27. End Try
    28. End Sub


    Habe einfach mal in einem anderen Registry-Eintrag von Skype dessen Eintrag mir genauer angesehen und dort die Angabe " --share-file="%V" entdeckt. Diese Tatsache habe ich dann mal eingebaut und siehe da, meine Arguments sind jetzt 2 lang.
    Im zweiten steht jetzt der kpl. Pfad der Datei, die ich mit Rechtsklick angeklickt habe.

    Mit dieser Info kann ich jetzt mein eigentliches Programm schreiben.

    Erst einmal vielen Dank für die schnelle Hilfe. Sollten sich noch weitere Probleme auftun, so melde ich mich noch einmal.

    Schönen Feiertag noch Euch allen.

    Gruß
    Volker

    Volker Bunge schrieb:

    nicht nur PDF-Dateien sondern eigentlich alle.
    Du willst Explorer-Unterstützung für ALLE Extensione?
    Was, wenn morgen eine völlig neue Extension auf den Markt kommt?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany,

    mein Programm soll dazu dienen (für einen Freund), immer wieder kehrende Abläufe möglichst einfach zu bearbeiten.

    Er kennt sich mit Computer nicht so gut aus und hat oben drein noch körperliche Einschränkungen. Er muss bspw. immer wieder Rechnungen scannen und diese an die Krankenkasse schicken. Hier wollte ich ein kleines Hilfsprogramm schreiben, mit der man auf vorgefertigte Schaltflächen klickt und damit entsprechende Aktionen auslöst.

    Es wird bspw. eine e-Mail an die Krankenkasse geschrieben (incl. des Anhanges, also die vorher angeklickte Datei). Diese Mail ist dann schon soweit fertig, dass er eigentlich nur noch auf Senden klicken muss. Die Angaben hierzu die braucht man dann nur einmal einzugeben und schon kann man auf einfache Art und Weise den Anhang verschicken.

    Wie das Programm am Ende aussieht, dass wird sich jetzt erst zeigen. Nur wenn ich das wichtigste Problem (siehe oben) nicht hinbekommen hätte, dann wäre das Programm so nicht realisierbar. Klar gebe es da noch andere Möglichkeiten (diese hätte ich dann vielleicht mal testen müssen), aber so kann man an jeder beliebigen Stelle das Programm starten.

    Ein Problem gibt es vielleicht jetzt schon: Wie muss ich vorgehen, wenn ich mehr als eine Datei markiere. Aber hierzu komme ich ggf. später noch.

    Mein Programm kann ja immer noch bestimmte Dateitypen nur zulassen. Aber das ist hier nur eine kleine Randbedingung.

    Gruß
    Volker
    @Volker Bunge OK.
    Wie wäre es mit Drag'nDrop?
    Da kannst Du jede beliebige Datei aud eine Form ziehen und in Abhängigkeit der Extension und / oder einer Vorauswahl per ComboBox / RadioButton tun, was zu tun ist.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Wäre auch eine Möglichkeit.

    Hätte ggf. einen Vorteil: Ich könnte hier gleich mehrere Dateien als Anhänge auswählen.

    Nachteil: Das Programm muss ständig sichtbar sein. (Gut, ist jetzt kein richtiger Nachteil, kann aber beim sonstigen Bedienen ggf. stören).

    Ich werde mal schauen, wie weit ich mit der Rechtsklick-Methode komme und ggf. auch Drag&Drop möglich machen.

    Gruß
    Volker
    @Volker Bunge:

    Schaust du hier: ookii.org/Blog/opening_files_via_idroptarget_in_net
    stackoverflow.com/questions/13…explorer-at-the-same-time
    Hier gibt es auch ein Sample: ookii.org%2Fdownload.ashx%3Fid%3DShellDropTargetSample Ist zwar C#, kann man ja nach VB.NET übersetzen.
    Mfg -Franky-