Hi.
In diesem kleinen Artikel hebe ich die Unterschiede zwischen Shell() und Process.Start() hervor. Es wird viel diskutiert, welche Funktion denn nun besser, älter oder neuer ist. Allgemein bekannt ist, dass Shell() schon seit langer Zeit existiert und Process.Start() erst in den .NET-Versionen von VB dazugekommen ist. Dabei lohnt sich ein Blick auf die Interna der beiden Aufrufe. Die ausführliche Erklärung der Parameter findet sich im MSDN - Links am Ende des Posts.
Shell:
Bei Process.Start kommt es darauf an, ob UseShellExecute des entsprechenden ProcessStartInfo-Objekts auf True oder False festgelegt ist:
Alle Aufrufe führen auf das Windows API zurück, was nicht weiter verwunderlich ist. Doch wo liegt nun der Unterschied genau?
ShellExecuteEx() wird von der DLL shell32.dll exportiert, während CreateProcess() von kernel32.dll exportiert wird. Das bedeutet, dass ShellExecuteEx() aus der Windows Shell stammt und CreateProcess einen Systemaufruf ("SysCall") darstellt. Ironischerweise verwendet der VB-Shell()-Aufruf gerade nicht die Windows Shell, um das übergebene Argument zu verarbeiten, Process.Start() in der Standardeinstellung UseShellExecute = True jedoch schon.
Der Vorteil der Windows Shell ist, dass damit auch Verknüpfungen und Dokumente aufgelöst werden können, was mit CreateProcess() nicht, also weder mit Shell(), noch mit Process.Start mit UseShellExecute = False, funktioniert. CreateProcess() kann laut Dokumentation nur ausführbare Dateien laden, aber keine Referenzen (Dokumente, Verknüpfungen) auflösen. Hierzu ein paar Beispiele:
"C:\document.doc" ist ein Microsoft Office-Dokument, "C:\myapp.exe" eine ausführbare Datei.
Der offensichtliche Nachteil von Shell() ist also, dass im Argument nur ausführbare Dateien stehen dürfen. Nicht ganz so offensichtlich ist, dass diese Methode jederzeit entfernt werden kann, denn sie wurde bereits in den Namespace Microsoft.VisualBasic ausgelagert, der nur Bestandteile aus älteren VB-Versionen <= 6 enthält. Es ist nicht gesichert, dass spätere Versionen des .NET Frameworks diese Rückwärtskompatibilität in diesem Ausmaß weiterführen.
Es stellt sich heraus, dass Process.Start() die universellere Funktion ist, welche mit der Unterstützung der Windows Shell einen größeren Funktionsumfang und vor allem eine enorme Toleranz gegenüber Eingaben besitzt. Daher sollte ihr der Vorzug gegenüber dem Shell()-Aufruf gegeben werden.
Zum Schluss noch die Links zur Dokumentation von...
Microsoft.VisualBasic.Interaction.Shell
System.Diagnostics.Process.Start(String)
CreateProcess (WinAPI)
ShellExecuteEx (WinAPI)
Ich hoffe, der Unterschied zwischen beiden Aufrufen ist klar geworden. Fragen, Lob, Kritik & Kommentare sind natürlich erlaubt / erwünscht.
Gruß
hal2000
In diesem kleinen Artikel hebe ich die Unterschiede zwischen Shell() und Process.Start() hervor. Es wird viel diskutiert, welche Funktion denn nun besser, älter oder neuer ist. Allgemein bekannt ist, dass Shell() schon seit langer Zeit existiert und Process.Start() erst in den .NET-Versionen von VB dazugekommen ist. Dabei lohnt sich ein Blick auf die Interna der beiden Aufrufe. Die ausführliche Erklärung der Parameter findet sich im MSDN - Links am Ende des Posts.
Shell:
VB.NET-Quellcode
- 'Signatur:
- Public Shared Function Shell(ByVal PathName As String, ByVal Optional Style As AppWinStyle = 2, ByVal Optional Wait As Boolean = False, ByVal Optional Timeout As Integer = -1) As Integer
- 'Der relevante interne Aufruf, der das angegebene Programm letztentlich ausführt:
- NativeMethods.CreateProcess(Nothing, PathName, Nothing, Nothing, False, &H20, ptr, Nothing, lpStartupInfo, lpProcessInformation)
Bei Process.Start kommt es darauf an, ob UseShellExecute des entsprechenden ProcessStartInfo-Objekts auf True oder False festgelegt ist:
VB.NET-Quellcode
Alle Aufrufe führen auf das Windows API zurück, was nicht weiter verwunderlich ist. Doch wo liegt nun der Unterschied genau?
ShellExecuteEx() wird von der DLL shell32.dll exportiert, während CreateProcess() von kernel32.dll exportiert wird. Das bedeutet, dass ShellExecuteEx() aus der Windows Shell stammt und CreateProcess einen Systemaufruf ("SysCall") darstellt. Ironischerweise verwendet der VB-Shell()-Aufruf gerade nicht die Windows Shell, um das übergebene Argument zu verarbeiten, Process.Start() in der Standardeinstellung UseShellExecute = True jedoch schon.
Der Vorteil der Windows Shell ist, dass damit auch Verknüpfungen und Dokumente aufgelöst werden können, was mit CreateProcess() nicht, also weder mit Shell(), noch mit Process.Start mit UseShellExecute = False, funktioniert. CreateProcess() kann laut Dokumentation nur ausführbare Dateien laden, aber keine Referenzen (Dokumente, Verknüpfungen) auflösen. Hierzu ein paar Beispiele:
"C:\document.doc" ist ein Microsoft Office-Dokument, "C:\myapp.exe" eine ausführbare Datei.
VB.NET-Quellcode
- 'Dieser Aufruf funktioniert - das Dokument wird in Word geöffnet.
- Process.Start("C:\document.doc")
- 'Diese beiden ebenso - die Anwendung wird ausgeführt
- Process.Start("C:\myapp.exe") 'Die Shell kann auch ausführbare Dateien laden...
- Shell("C:\myapp.exe")
- 'Die folgenden Aufrufe funktionieren NICHT:
- Shell("C:\document.doc") ' <-- Exception
- Dim psi As New ProcessStartInfo
- psi.UseShellExecute = False
- psi.FileName = "C:\document.doc" ' ausführbare Dateien (!) funktionieren auch mit UseShellExecute = False
- Process.Start(psi) ' <-- Exception
Der offensichtliche Nachteil von Shell() ist also, dass im Argument nur ausführbare Dateien stehen dürfen. Nicht ganz so offensichtlich ist, dass diese Methode jederzeit entfernt werden kann, denn sie wurde bereits in den Namespace Microsoft.VisualBasic ausgelagert, der nur Bestandteile aus älteren VB-Versionen <= 6 enthält. Es ist nicht gesichert, dass spätere Versionen des .NET Frameworks diese Rückwärtskompatibilität in diesem Ausmaß weiterführen.
Es stellt sich heraus, dass Process.Start() die universellere Funktion ist, welche mit der Unterstützung der Windows Shell einen größeren Funktionsumfang und vor allem eine enorme Toleranz gegenüber Eingaben besitzt. Daher sollte ihr der Vorzug gegenüber dem Shell()-Aufruf gegeben werden.
Zum Schluss noch die Links zur Dokumentation von...
Microsoft.VisualBasic.Interaction.Shell
System.Diagnostics.Process.Start(String)
CreateProcess (WinAPI)
ShellExecuteEx (WinAPI)
Ich hoffe, der Unterschied zwischen beiden Aufrufen ist klar geworden. Fragen, Lob, Kritik & Kommentare sind natürlich erlaubt / erwünscht.
Gruß
hal2000