pat.bat
Goto Top

PowerShell-VB - Pfad wird bei Parameterübergabe abgeschnitten

Hallo zusammen,

ich stoße momentan auf folgendes Problem:

in meinem VB.Net Programm rufe ich ein Powershell Skript auf und übergebe 2 Parameter die in VB vorher gefüllt werden:

        Dim Zahlliste As String = txtBoxFile.Text.ToString()
        procStartInfo.Arguments = "-File " & Application.StartupPath & "\Skripts\ZahllistenErstellen.ps1 -PfadText " & Zahlliste & " -Speicherpfad " & PathToday  

in PowerShell wird das dann wie folgt verarbeitet:

param(
    [String]$PfadText,
    [String]$Speicherpfad
)

Push-Location $(Split-Path $Script:MyInvocation.MyCommand.Path)

$DMYToday = Get-Date -Format "dd-MM-yyyy"  

$TempPath = "$env:TEMP\Zahllisten\"  

If (!(Test-Path $TempPath))
{
    mkdir $TempPath
}
Else
{
    Remove-Item -Path $TempPath -Force -Recurse
    mkdir $TempPath
}

$Textdatei = "$PfadText"  

$CSV = "$env:TEMP\Zahllisten\Zahlliste.csv" # in Temp Ordner generieren  
$arrCols = @("Buchungnummer", "angew.", "Abwahl")  

((Get-Content "$Textdatei") -replace '^\s+','' ) -replace ' *\t *',';' | `  
convertfrom-csv -Delimiter ";" | `  
select * -excludeproperty $arrCols | `
export-csv -path $CSV -delimiter ";" -Encoding utf8 -NoTypeInformation  

Da der Pfad in $PfadText allerdings Leerzeichen enthält schneidet er mir den Pfad immer ab, obwohl ich ihn auch hier nochmal als String an eine Variable $Textdatei übergebe.

ps fehler

Der Vollständige Pfad hätte so aussehen sollen:

G:\FD_50_Bank\System\Prosoz Batch Verwaltung\Zahlliste\Archiv\2019\10-2019\2019-10-10\Gesamt.txt

Den Vorgang Debugge ich aus Visual Studio heraus, sodass ich den PS Code leider nicht direkt debuggen kann.


Meine Frage nun, wo liegt der Fehler? Ist er bei der Parameter Abfrage in PS ganz oben oder warum gibt er nicht den gesamten String rüber? In VB ist der Pfad noch in Ordnung.

Vielen Dank im Voraus.

Content-Key: 505311

Url: https://administrator.de/contentid/505311

Ausgedruckt am: 28.03.2024 um 16:03 Uhr

Mitglied: emeriks
Lösung emeriks 16.10.2019 aktualisiert um 10:40:07 Uhr
Goto Top
Hi,
im VB.Net mit "" um den Pfad arbeiten

        Dim Zahlliste As String = txtBoxFile.Text.ToString()
        procStartInfo.Arguments = "-File """ & Application.StartupPath & "\Skripts\ZahllistenErstellen.ps1"" -PfadText """ & Zahlliste & """ -Speicherpfad """ & PathToday & """"  

E.

Edit:
Für sowas empfiehlt sich dann auch String.Format
        Dim Zahlliste As String = txtBoxFile.Text.ToString()
        procStartInfo.Arguments = String.Format("-File ""{0}\Skripts\ZahllistenErstellen.ps1"" -PfadText ""{1}"" -Speicherpfad ""{2}"" ", Application.StartupPath, Zahlliste, PathToday)  
Mitglied: 141320
141320 16.10.2019 aktualisiert um 10:38:54 Uhr
Goto Top
Na überall Anführungszeichen vergessen face-wink, das sollte man doch eigentlich wissen wenn man Pfade in der Konsole als Parameter übergibt die Leerzeichen enthalten!
procStartInfo.Arguments = "-File """ & Application.StartupPath & "\Skripts\ZahllistenErstellen.ps1"" -PfadText """ & Zahlliste & """ -Speicherpfad """ & PathToday & """"  

edit too late
Mitglied: Pat.bat
Pat.bat 16.10.2019 um 11:41:29 Uhr
Goto Top
Danke das hat geholfen.

Leider hat mein Skript noch ein anderes Problem und ich finde nicht den Fehler.

Wenn ich das Skript direkt über VSCode starte, bekomme ich zwar ein paar Fehler, aber es läuft trotzdem durch und macht was es soll.

Starte ich das Skript nun über meine VB Anwendung, kommt folgender Fehler:

psfehler

Wenn ich das Skript direkt ausführe, übergebe ich die Parameter, die normal über die VB App kommen würden, direkt. Jedoch gleicher Pfad etc.
Dann erstellt mir die Excel Dateien.

Ich poste einfach mal das gesamte Skript hier.

Als erstes die Sub in VB:

    Private Sub BGW_DoWork(sender As Object, e As DoWorkEventArgs) Handles BGW.DoWork
        Dim PathToday As String
        PathToday = "\\Vdm-11\lup-daten\FD_50_Bank\Einrichtungen_Zahllisten\" _  
                                & Format(DateTimePicker1.Value, "yyyy") & "\" & Format(DateTimePicker1.Value, "MM-yyyy") & "\" & Format(DateTimePicker1.Value, "dd-MM-yyyy") & "\"  

        ' Wenn Ausgabeverzeichnis noch nicht existiert, dann erstellen  
        If Not (Directory.Exists(PathToday)) Then
            Directory.CreateDirectory(PathToday)
        End If

        Dim proc As Process
        Dim procStartInfo As ProcessStartInfo
        procStartInfo = New ProcessStartInfo
        procStartInfo.FileName = "powershell.exe"  
        'procStartInfo.CreateNoWindow = True  
        'procStartInfo.UseShellExecute = False  
        Dim Zahlliste As String = txtBoxFile.Text.ToString()
        procStartInfo.Arguments = String.Format("-File ""{0}\Skripts\ZahllistenErstellen.ps1"" -PfadText ""{1}"" -Speicherpfad ""{2}"" -Date ""{3}"" ", Application.StartupPath, Zahlliste, PathToday, Format(DateTimePicker1.Value, "dd.MM.yyyy"))  
        proc = Process.Start(procStartInfo)
        proc.WaitForExit()

        ' Prüfen ob Temp Ordner noch existiert, ansonsten löschen.  
        If (Directory.Exists(Path.GetTempPath & "\Zahllisten")) Then  
            Directory.Delete(Path.GetTempPath & "\Zahllisten", True)  
        End If

        MsgBox("Fertig")  
    End Sub

Und dann das eigentliche PS Skript:

param(
    [String]$PfadText,
    [String]$Speicherpfad,
    [String]$Date
)

Push-Location $(Split-Path $Script:MyInvocation.MyCommand.Path)

# Für Debugging Zwecke
$YearToday = Get-Date -Format "yyyy"  
$MYToday = Get-Date -Format "MM-yyyy"  
$DMYToday = Get-Date -Format "dd-MM-yyyy"  

$PfadText = "H:\Entwicklung\Zahllaufkalender\Zahllaufkalender\Zahllaufkalender\bin\Debug\Zahlliste\Gesperrt.txt"  
#$PfadText = "H:\Entwicklung\Zahllaufkalender\Zahllaufkalender\Zahllaufkalender\bin\Debug\Zahlliste\Gesperrt.txt" 
$Speicherpfad = "\\Vdm-11\lup-daten\FD_50_Bank\Einrichtungen_Zahllisten\$YearToday\$MYToday\$DMYToday\"  
$Date = Get-Date -Format "dd.MM.yyyy"  

# Temp Ordner erstellen, wenn noch nicht vorhanden
$TempPath = "$env:TEMP\Zahllisten\"  
If (!(Test-Path $TempPath))
{
    mkdir "$TempPath"  
}
Else
{
    Remove-Item -Path "$TempPath" -Force -Recurse  
    mkdir "$TempPath"  
}

$CSV = "$env:TEMP\Zahllisten\Zahlliste.csv" # in Temp Ordner generieren  
$arrCols = @("Buchungnummer", "angew.", "Abwahl")  
#$arrNames = @("*ANKER*", "*Kloster*") 

((Get-Content "$PfadText") -replace '^\s+','' ) -replace ' *\t *',';' | `  
convertfrom-csv -Delimiter ";" | `  
select * -excludeproperty $arrCols | `
# where { $_."ZE-Name" -like $arrNames } |  ` 
export-csv -path $CSV -delimiter ";" -Encoding utf8 -NoTypeInformation  

$datasets = $(import-csv $csv -delimiter ";")  
foreach($dataset in $datasets) {
    
    $dataset | export-csv -path "$TempPath$($dataset.'ZE-Name').csv" -Append -Delimiter ";" -Encoding UTF8 -NoTypeInformation -Force  

}

Remove-Item -Path $CSV
$Files = Get-ChildItem -Path $TempPath

$xlo = New-Object -ComObject excel.application
$xlo.visible = $false
$xlo.DisplayAlerts = $false

foreach ($File in $Files) 
{
# csv-datei in Excel einlesen
$xlw = $xlo.Workbooks.Add("$TempPath$File")  
$xls = $xlw.worksheets.Item(1)

# Spalte löschen
$xlo.ActiveSheet.Range("L:L").EntireColumn.Delete()  

# Daten in Tabelle umwandeln
$ListObject = $xlo.ActiveSheet.ListObjects.Add([Microsoft.Office.Interop.Excel.XlListObjectSourceType]::xlSrcRange, $xlo.ActiveCell.CurrentRegion, $null, [Microsoft.Office.Interop.Excel.XlYesNoGuess]::xlYes)
$ListObject.Name = "TableData"  
$ListObject.TableStyle = "TableStyleMedium9"  

# Zeile hinzufügen
$eRow = $xlo.ActiveSheet.cells.item(1,1).entireRow
$active = $eRow.activate()
for ($i=1; $i -le 5; $i++)
{
    $active = $eRow.insert($xlShiftDown)
} 

# Logo hinzufügen
$imgPath = 'G:\FD_50_Bank\System\Prosoz Batch Verwaltung\Media\LUP Logo.jpg'  
$LinkToFile = $false
$SaveWithDocument = $true
$Left = 1
$Top = 1
$Width = 300
$Height = 67
$img = $xlo.ActiveSheet.Shapes.AddPicture($imgPath, $LinkToFile, $SaveWithDocument, $Left, $Top, $Width, $Height)
$xlo.Speech.Speak("Bild wurde eingefügt")  

$xlo.ActiveWindow.DisplayGridlines = $false

# Spaltenbreite anpassen
$xlo.ActiveSheet.Range("A:K").EntireColumn.AutoFit()  

# Speichern der Excel Datei
$Filename = $File -replace ".csv","" -replace ",.csv", ""  
If ($Filename.EndsWith(","))  
{
   $Filename = $Filename -replace ",",""  
}

If ("$PfadText" -like "*Gesamt.txt")  
{ 
    if (!(Test-Path "$Speicherpfad$Filename")){   
    md -Path "$Speicherpfad$Filename"  
    }
    $xlo.ActiveWorkbook.SaveAS( "$Speicherpfad$Filename\Gesamt_$Date.xlsx", [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault)  
}
elseif ("$PfadText" -like "*Gesperrt.txt")   
{
    if (!(Test-Path "$Speicherpfad$Filename")){   
        md -Path "$Speicherpfad$Filename"  
        }
    $xlo.ActiveWorkbook.SaveAS( "$Speicherpfad$Filename\Gesperrt_$Date.xlsx", [Microsoft.Office.Interop.Excel.XlFileFormat]::xlWorkbookDefault)   
}

$xls = $null
$xlw.Close()
}

$xlo.Quit()

# TEMP Datei löschen, da nicht mehr gebraucht
Remove-Item -Path $TempPath -Force -Recurse

Pop-Location


Ich hoffe mein Praxisbuch kommt bald, damit ich hier nicht mehr soviel posten muss :D. Aber ich verstehe nicht warum es über die App nicht funktioniert, und über das Skript direkt alles einigermaßen ordentlich ausgeführt wird. Es muss ja theoretisch ein Fehler bei der Übergabe der Parameter sein, Jedoch sind die Pfad in VB und PS gleich, soweit ich sehe.
Mitglied: emeriks
emeriks 16.10.2019 aktualisiert um 11:49:01 Uhr
Goto Top
In PS-Script übersteuerst Du die Script-Parameter in Zeilen 14 & 16. Soll das so sein?

In VB.Net, Zeile 4: "\" am Ende? Soll das so sein?
Mitglied: Pat.bat
Pat.bat 16.10.2019 um 12:07:22 Uhr
Goto Top
In Zeile 14 und 16 war das nur zu debugging Zwecken hinterlegt, wenn ich das Skript ohne die VB-App ausführe. Ansonsten ist das auskommentiert.

in VB Zeile 4 muss das "\" am Ende, sonst erstellt er mir einen Ordner pro Zahlungsempfänger mit Datum vorne weg.

Ich möchte aber die Ordner pro ZE in dem Datumsordner haben:

So würde er es machen ohne dem Backslash, was falsch wäre:

falsch

und so soll es sein: (wenn ich das PS Skript direkt ausführe):

richtig



Wenn ich das Backslash in VB entferne führt erstellt er mir die Excel Dateien, aber halt nur in den falschen Ordner. Lasse ich das Backslash in VB stehen, gibts wieder die PS Fehlermeldung mit dem Illegalen Zeichen, siehe oben.
Kurios ist, das dass Backslash, wenn ich den Pfad direkt im PS Skript übergebe funktioniert...

anbei nochmal der Fehler aus PS:

psfehler
Mitglied: emeriks
emeriks 16.10.2019 um 12:12:58 Uhr
Goto Top
Setze mal im PS vor Zeile 112
Write-Host "$Speicherpfad$Filename\Gesperrt_$Date.xlsx"  
Was kommt dabei heraus?
Mitglied: Pat.bat
Pat.bat 16.10.2019 um 12:23:38 Uhr
Goto Top
Ups was macht er denn da:

writehostausgabe

Wenn ich jetzt in VB das Backslash entferne und füge ein Backslash in PS zwischen $Speicherpfad und $Filename ein, funktioniert es.

Aber wie er das oben im Bild erzeugt ist mir schleierhaft und das nur weil der letztes Backslash über VB kommt ???
Mitglied: 141320
141320 16.10.2019 aktualisiert um 12:43:34 Uhr
Goto Top
Aber wie er das oben im Bild erzeugt ist mir schleierhaft und das nur weil der letztes Backslash über VB kommt ???
Weil der Backslash in der CMD in der du ja den PS Befehl ausführst ein Escape-Zeichen ist und du damit das Anführungszeichen als gewollten String kennzeichnest, und dieser ist nunmal in einem Pfad illegal!
https://www.robvanderwoude.com/escapechars.php
Setze den Pfad in den Argumenten in 'single quotes' bzw. Hochkommas oder escape ihn mit \\ dann ist das egal.