Powershell findet die exe nicht?
Ich habe folgendes Powershellscript:
# Nach dem Quellordner fragen
$sourceFolder = Read-Host "Quellordner"
# Nach dem Zielordner fragen
$targetFolder = Read-Host "Zielordner"
# Der Pfad zu deiner ausführbaren Datei
$exePath = "D:\ManualToHelpCmdExe\ManualToHelpCmd.exe"
# Aufruf des Programms mit den angegebenen Parametern
& $exePath $sourceFolder $targetFolder
Das funktioniert auch ohne Probleme bloß soll bei der Angabe der exe nicht spezifisch ein Pfad angegeben sein sondern nur nach er Exe gesucht werden, sodass auch andere das Script benutzen können und da dachte ich an diese Zeile:
$exePath = ".\ManualToHelpCmd.exe"
Aber das geht nicht, da kommt nur, dass es als exe nicht gefunden werden kann.
Woran liegt das?
2 Antworten
Wenn Du nicht weißt wo sich die gewünschte Datei befindet musst Du Powershell eben danach suchen lassen.
Laufwerk C: ab dem Rootverzeichnis durchsuchen:
$exePath = (Get-ChildItem -Path 'c:\' -Filter 'ManualToHelpCmd.exe' -Recurse -ErrorAction SilentlyContinue).FullName
$exePath
etwas komplexer wird es wen man eine Datei möglichst schnell und effizient in allen Laufwerken finden möchte (am besten in allen LWs gleichzeitig ---ich habe 13---):
$SearchFile='ManualToHelpCmd.exe' #Datei welche gesucht werden soll
$ExcludeFolders = 'Windows','Video' #Hauptordner in Laufwerken, welche überhauptnicht durchsucht werden sollen
#ermittle alle lokalen Laufwerke (HDD,SSD,UsB,SD...) (keine CD,Dvd)
$Drives = (Get-CimInstance -ClassName Win32_LogicalDisk -Filter 'DriveType = 3 or DriveType = 2').DeviceID -as [Array]
#das eigentliche Arbeitspferd
$Worker = {
param(
[Array]$Drives = @(0),
[String]$Filter,
[Array]$ExcludeFolders
)
$Drives|%{
(gci "$_\" -File -Filter $Filter -ea sil).Fullname
(gci "$_\" -Dir|? Name -notin $ExcludeFolders|gci -File -Filter $Filter -r -ea sil).Fullname
}
}
#die Suche starten...
if ($Drives.Length -lt 2) { #wenn wir nur ein (Physikalisches) Laufwerk haben können wir die Verteilung auf mehrere Jobs sparen, einfach den Worker direkt ausführen
Write-Host $Drives.Length 'physical Disk, searching single Threaded in Drives: ' -fo mag
$Result = & $worker (,$Drives) -Filter $SearchFile -Exclude $ExcludeFolders
}
else { #bei mehreren Laufwerken die Arbeit auf mehrere parallele Jobs verteilen
Write-Host 'init parallel Search for Drives :' -fo mag
$Jobs = $Drives|
ForEach-Object {
Write-Host create Job for Drive: $_ -fo green
Start-Job -ScriptBlock $worker -ArgumentList ($_ , $SearchFile, $ExcludeFolders)
}
#$Jobs|ft
$Result = $Jobs|
Wait-Job|
Receive-Job|
Where-Object {$_}
}
$Result #das Ergebnis (können auch mehrere Dateien gleichen namens sein)
pause
...sorry für die edits, bin heute etwas "Lost" (sommergrippe 😵😷🤒)
Alles gut, das hat auf jeden Fall mega geholfen und gute Besserung!
Naja, es ist nur logisch, dass die .exe nicht gefunden wird.
Es sind zwei Faktoren zu berücksichtigen:
- Speicherort der .exe
- Speicherort des Skripts
Jedes System ist anders. Ob es tatsächlich ein D-Laufwerk gibt, weiß du nicht. Manche vergeben einen anderen Buchstaben.
Den Pfad hard-coded vorzugeben ist immer eine schlechte Idee. Entweder gibst du dem Benutzer die Möglichkeit über eine .ini- oder .cfg-Datei seinen Speicherort anzugeben oder - komplizierter - du scannst ein Laufwerk nach dem Ordner und nach der Datei, was u. U. rekursiv geschehen müsste.
Wird das Skript mit der .exe ausgeliefert? Oder sind diese zwei Teile unabhängig voneinander?
Schwierig zu erklären, man muss bestimtme Parameter reingeben in die exe, aber das muss natürlich nicht durch ein Script passieren, daher würde ich sagen, dass sie unabhängig voneinander sind
Probiere es mal so:
Inhalt config.ini
D:\ManualToHelpCmdExe\ManualToHelpCmd.exe
Das Skript
#Pfad der .exe aus der ini-Datei lesen
$path_from_ini = Get-Content "$PSScriptRoot\config.ini"
# Nach dem Quellordner fragen
$sourceFolder = Read-Host "Quellordner"
# Nach dem Zielordner fragen
$targetFolder = Read-Host "Zielordner"
# Der Pfad zu deiner ausführbaren Datei
$exePath = $path_from_ini
Das Powershell-Skript und die config.ini müssen in einem Ordner liegen, damit $PSScriptRoot weiß, wo die config.ini zu lesen ist.
Vielleicht reicht es für deine Bedürfnisse bereits aus.
Ist eine möglichkeit, aber zusätzlich eine Datei zu erstellen ist nicht meins, kann das Script nicht von alleine nach der exe suchen?
Ich ignoriere einfach alles, was ich in der Antwort geschrieben habe :)
Get-ChildItem -Path "D:" -Include *.exe -Recurse | Where-Object { !$PsIsContainer -and [System.IO.Path]::GetFileNameWithoutExtension($_.Name) -eq "ManualToHelpCmd" }
echt? Ok der Weg funktioniert. aber:
- Get-ChildItem -Path "D:" -Include *.exe -Recurse => sucht erstmal alle .exe auf dem Laufwerk , das könnten bei C: durchaus zigtausende sein. totaler Käse dagegen hat gci den -filter-parameter
- dann hächelst Du die (evtl.Riesen)Liste mit Where-Objeckt nochmal durch und es wird noch schlimmer!!!:
- du testest erst jetzt ob es evtl ein Ordner ist (bei . exe unwahrscheinlich) und sattelst auch noch auf .Net-Methoden um, obwohl das von gci gelieferte Fileobject bereits alles beinhaltet ($_.BaseName ist der nackte Name).
- warum reduzierst du überhaupt auf den nackten Name? $_.Name) -like 'ManualToHelpCmd.exe' ohne .Net (aber unötig wenn Du in gci den -Filter auf 'ManualToHelpCmd.exe gesetzt hättest)
wie gesagt geht, ist aber jede Menge Doppelgemoppel
ps: die Kritik ist nicht bös gemeint, Sicher hast Du das Erstbeste irgendwo kopiert, ( mach ich auch gelegentlich) aber man sollte solchen Schnulli nicht an Anfänger weitergeben. Der nächste ders sieht denkt sich "cleanercode > 20 Jahre in der Softwareentwicklung" ...der muss es ja wissen...
Ich bin ach nicht perfekt, aber ich vesuch so wenig wie möglich müll weiterzugeben.
Ich würde deine Kritik annehmen - aber es scheint, als hättest du meine Antwort sowie die Kommentare nicht oder nicht richtig gelesen. Ich habe bereits von diesem Weg abgeraten.
Meine und deine erweiterte Lösung könnten jegliche Virenscanner oder Logger in Alarmbereitschaft versetzen. Von Admin-Rechten oder Performance fange ich lieber nicht an - der Fragende ist schließlich in Windows unterwegs :-P
Der einfachste Weg wäre eine Eingabemöglichkeit für den User, denn nur er weiß, wo sich die Datei befindet. Danach wären pre- und post-condition Checks sinnvoll.
Aber stumpfe Rekursion im Dateisystem anzuwenden - igit.
Warum sollte bei einer Dateisuche Virenscanner in Alarmbereitschaft versetzt werden? (Solange man keine Schreiboperation versucht interessiert sich kein Scanner) Get-ChildItem tut nichts anderes als die Dateisuche im Explorer
Klar, ohne Admintechte meckert gci normalerweise, wenn bei einigen Systemdateien das auslesen der Properties verweigert wird . Das fange ich durch "-ErrorAction SilentlyContinue" ab, so das dergleichen Dateien einfach ignoriert werden . (gehen dem Nutzer ohnehin nichts an)
denn nur er weiß, wo sich die Datei befindet
...seltsame Philosophie...😱
ist schließlich in Windows unterwegs :-)
...gerade deshalb sollte man vom Nutzer nicht zuviel erwarten. (Was denkst Du, wie Oma Meier reagiert, wenn man von ihr erwartet, das sie weiß wo sich welche Datei befindet)
Solche Sachen weiß im Allgemeinen eben kaum ein Windowsnutzer. Damit ein Normalnutzer eben nicht unkontrolliert anfängt wild herumzusuchen erledigt man dies für ihn.
Aus meiner Erfahrung heraus, sollte man einem Nutzer so wenig wie möglich Eingriffsmöglichkeiten überlassen , sonst kommt er auf dumme Ideen.
Lieber eine automatisierte rekursive Suche, als eine möglicherweise fehlerhafte Nutzereingabe.
Stimme ich dir selbstverständlich zu, aber für
möglicherweise fehlerhafte Nutzereingabe.
wurde Fehlerhandling erfunden.
Damit greift der User kaum ins System ein und greift nur auf das zu, worauf er zugreifen sollte => SoC.
...seltsame Philosophie...😱
Wieso denn? Wenn ich eine Datei an einem bestimmten Speicherort hinterlege, dann sollte ich wissen, wo das ist. Da Oma Meier und Opa Gerd nicht die Zielgruppe dieses Skriptes sind, passt meine Philosophie an sich. Und falls doch, können Oma und Opa uns Helden anrufen :-)
Ich merke schon, wir sollten uns vernetzen :) Die Diskussionen würden mir durchaus Spaß machen.
Danke mir geht es darum, dass das Script auf mehreren Pc's woanders liegt genauso wie die exe und das wollte ich sozusagen verallgemeinern.