none
Powershell: Ordner mit Filechooser auswählen RRS feed

  • Allgemeine Diskussion

  • In einem größerem Skript brauche ich einen Dialog, um ein Verzeichnis auszuwählen. Mit dem Folderchooser war das kein großes Problem. Ich mag jedoch diesen Dialog nicht und würde lieber den Filechooser verwenden. Dafür habe ich bei Github ein Skript gefunden:
    https://gist.github.com/IMJLA/1d570aa2bb5c30215c222e7a5e5078fd
    Für sich allein funktioniert dieses einwandfrei. Ich hatte jedoch Probleme, es mit meinem bisherigen Skript zusammenzubringen. Mit viel Bastelei habe ich dann dieses zum Laufen gebracht:

    # Filechooser vorbereiten, dies ist von Github uebernommen
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    $AssemblyFullName = 'System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
    $Assembly = [System.Reflection.Assembly]::Load($AssemblyFullName)
    $OpenFileDialog = [System.Windows.Forms.OpenFileDialog]::new()
    $OpenFileDialog.AddExtension = $false
    $OpenFileDialog.CheckFileExists = $false
    $OpenFileDialog.DereferenceLinks = $true
    $OpenFileDialog.Filter = "Folders|`n"
    $OpenFileDialog.Multiselect = $false
    $OpenFileDialog.Title = "Select folder"
    $OpenFileDialogType = $OpenFileDialog.GetType()
    $FileDialogInterfaceType = $Assembly.GetType('System.Windows.Forms.FileDialogNative+IFileDialog')
    $IFileDialog = $OpenFileDialogType.GetMethod('CreateVistaDialog', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($OpenFileDialog, $null)
    $OpenFileDialogType.GetMethod('OnBeforeVistaDialog', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($OpenFileDialog, $IFileDialog)
    [uint32]$PickFoldersOption = $Assembly.GetType('System.Windows.Forms.FileDialogNative+FOS').GetField('FOS_PICKFOLDERS').GetValue($null)
    $FolderOptions = $OpenFileDialogType.GetMethod('get_Options', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($OpenFileDialog, $null) -bor $PickFoldersOption
    $FileDialogInterfaceType.GetMethod('SetOptions', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($IFileDialog, $FolderOptions)
    $VistaDialogEvent = [System.Activator]::CreateInstance($AssemblyFullName, 'System.Windows.Forms.FileDialog+VistaDialogEvents', $false, 0, $null, $OpenFileDialog, $null, $null).Unwrap()
    [uint32]$AdviceCookie = 0
    $AdvisoryParameters = @($VistaDialogEvent, $AdviceCookie)
    $AdviseResult = $FileDialogInterfaceType.GetMethod('Advise', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($IFileDialog, $AdvisoryParameters)
    $AdviceCookie = $AdvisoryParameters[1]
    # Ende von Github uebernommen
    
    # So habe ich es bisher gemacht:
    $objForm = New-Object System.Windows.Forms.Form
    [System.Windows.Forms.Application]::EnableVisualStyles()
    $objForm.Size = New-Object System.Drawing.Size(800, 500)
    $folderChooseBtn = New-Object System.Windows.Forms.Button
    $folderChooseBtn.Location = New-Object System.Drawing.Size($x, $y)
    $folderChooseBtn.Size = New-Object System.Drawing.Size(100, 20)
    $folderChooseBtn.Text = "Ordner wählen"
    $folderChooseBtn.Name = "Ordnerwahl"
    $folderChooseBtn.Add_Click( {
            # Oeffnen des Filechoosers, von Github uebernommen
            $Result = $FileDialogInterfaceType.GetMethod('Show', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($IFileDialog, [System.IntPtr]::Zero)
            $FileDialogInterfaceType.GetMethod('Unadvise', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($IFileDialog, $AdviceCookie)
            if ($Result -eq [System.Windows.Forms.DialogResult]::OK) {
                $FileDialogInterfaceType.GetMethod('GetResult', @('NonPublic', 'Public', 'Static', 'Instance')).Invoke($IFileDialog, $null)
            }
            Write-Host $OpenFileDialog.FileName
            # Ende von Github uebenommen
        })
    $objForm.Controls.Add($folderChooseBtn)
    [void] $objForm.ShowDialog()
    
    Read-Host -Prompt "Press Enter to exit"

    Ich habe das dumpfe Gefühl, dass die Art und Weise, wie ich beides vermengt habe, nicht so optimal ist und bitte um Durchsicht und Verbesserungsvorschläge.

    Edit: Wie man wahrscheinlich an dem Code schon sieht, stehe ich noch ganz am Anfang mit Powershell. Bin jedoch schon mal sehr angetan davon: Man kann ein GUI machen und auf das Netz zugreifen.


    Dienstag, 15. Oktober 2019 08:55

Alle Antworten

  • Inzwischen habe ich intensiv weiter gesucht und diesen Thread gefunden:

    https://social.technet.microsoft.com/Forums/windows/en-US/3aa84e9f-c1bc-4e5a-943b-f6d8437c59fa/need-help-creating-gui-to-select-folder-but-that-looks-like-openfiledialog-not-using-the?forum=winserverpowershell

    Der Folderchooser der dort vorgeschlagen wird ist perfekt und ich werde ihn verwenden.

    Trotzdem würde ich gern die Zusammenhänge bei dem Skript von Github in meinem ersten Posting besser verstehen. Erklärungen dazu sind deshalb weiter willkommen.

    Dienstag, 15. Oktober 2019 15:39