peterleb
Goto Top

Selbsterstelltes VBScript führt zu Fehlermeldung: Diese App kann auf dem PC nicht ausgeführt werden

Hallo Mädels und Jungs,

habe ein kleines VBScript geschrieben, welches den Namen einer ausführbaren Datei (*.exe) um die Dateiversion ergänzen soll, wenn eine vorhanden ist.
Also aus "EssentialPIMPro.exe" soll "EssentialPIMPro.9.10.6.exe" werden.

Mit Wscript.Arguments kann eine Datei übergeben und somit ein Kontextmenüeintrag im Explorer eingerichtet werden.
Zu Testzwecken ist eine Variable mit einem existierenden Dateinamen eingebaut, wenn kein Argument übergeben wird.
Hier "F:\vs_community.exe".
Die VBS-Datei ist in"C:\Scripts" gespeichert.

Nun folgendes Phänomen: Klicke ich die VBS-Datei zum Ausführen an, wird mir brav der neue Dateiname "F:\vs_community.16.9.31105.61.exe" angezeigt.
Führe ich das Script jedoch aus dem Explorer-Kontextmenü aus, poppt eine Warnmeldung auf:

"Diese App kann auf dem PC nicht ausgeführt werden. Wenden Sie sich an den Softwareherausgeber, um eine geeignete Version für Ihren PC zu finden"

Für hilfreiche Tipps wäre ich sehr dankbar.
Gruß
Peter

Content-Key: 1305748975

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

Ausgedruckt am: 19.03.2024 um 06:03 Uhr

Mitglied: PeterleB
PeterleB 25.09.2021 aktualisiert um 15:52:49 Uhr
Goto Top
Habe jetzt noch ein Hilfsscript angelegt, um die VBS als Admin zu starten.
Doch auch das ändert nichts.

adminstart-fileversion.vbs

 Set objShell = CreateObject("Shell.Application")   
 Set objFolder = objShell.Namespace("C:\")   
 Set objFolderItem = objFolder.ParseName("C:\Scripts\GetFileVersion.vbs") objFolderItem.InvokeVerb "runas"  

Übrigens führt mein Script bisher die Umbenennung noch gar nicht aus, sondern zeigt erstmal in einem Wscript.Echo den möglichen neuen Namen an, es finden also gar keine Dateioperationen statt.

Gruß
Peter
Mitglied: beidermachtvongreyscull
beidermachtvongreyscull 26.09.2021 um 07:08:10 Uhr
Goto Top
Moin,

stell doch mal das komplette Script zur Verfügung. Das würde Spekulationen reduzieren.

Gruß
bdmvg
Mitglied: PeterleB
PeterleB 26.09.2021 aktualisiert um 09:28:18 Uhr
Goto Top
Hallo,

mache ich gern:

'GetFileVersion.vbs  
' inspiriert von http://stackoverflow.com/questions/2976734/how-to-retrieve-a-files-product-version-in-vbscript  
Dim objShell, objFolder, objFolderItem, i, j 

Set FSO=CreateObject("Scripting.FileSystemObject")  
If Wscript.Arguments.Count > 0 then
  sFullFileName = Wscript.Arguments(0)
Else
    sFullFileName ="F:\vs_community.exe"  
End if  
If FSO.FileExists(sFullFileName) Then
    sFilePath= FSO.GetParentFolderName(sFullFileName)
    sProgram = FSO.GetFileName(sFullFileName)
    Set objShell = CreateObject("Shell.Application")  
    Set objFolder = objShell.Namespace(sFilePath)
    Set objFolderItem = objFolder.ParseName(sProgram)
    Dim arrHeaders(300)
    For i = 0 To 300
        arrHeaders(i) = objFolder.GetDetailsOf(objFolder.Items, i)
      ' WScript.Echo i &"- " & arrHeaders(i) & ": " & objFolder.GetDetailsOf(objFolderItem, i)  
        If lcase(arrHeaders(i))= "dateiversion" Then  
            'WScript.Echo arrHeaders(i) & ": " & objFolder.GetDetailsOf(objFolderItem, i)  
            'WScript.Echo "Filename: " & sProgram & " (" & sFilePath & ")"  
            sVersion = objFolder.GetDetailsOf(objFolderItem, i)
            sBaseName = FSO.GetBaseName(sFullFileName)
            sExt = FSO.GetExtensionName(sFullFileName)
            sNewName = sFilePath & sBaseName & "." & sVersion & "." & sExt  
            WScript.Echo "Neuer Dateiname: " & sNewName  
            Exit For
        End If

        'If lcase(arrHeaders(i))= "produktversion" Then  
        '    WScript.Echo arrHeaders(i) & ": " & objFolder.GetDetailsOf(objFolderItem, i)  
        '    j=j+1  
        'End if  
        'If (j = 2) then  
        '  Exit For  
        'End If  
    Next
End If

Anstelle "WScript.Echo "Neuer Dateiname: " & sNewName" soll dann mal
FSO.MoveFile sFullFileName sNewName
ausgeführt werden.

Ich denke, dass es kein Problem des Scriptes ist, sondern eher die Tatsache, dass die Kontextmenüverknüpfung auf EXE-Dateien zugreifen will.

Gruß
Peter
Mitglied: beidermachtvongreyscull
beidermachtvongreyscull 26.09.2021 aktualisiert um 10:53:13 Uhr
Goto Top
Das Script sieht auf den ersten Blick gut aus.

Ich nehme an, dass der Aufruf aus dem Kontextmenü falsch abläuft.

Hast Du mal geprüft, was das Script als Argument bekommt und wie es das weiterverarbeitet?
Du hast keine Fehlerbehandlung drin. Es kann also sein, dass im Script dann etwas schief läuft.

Gruß
Andreas
Mitglied: colinardo
Lösung colinardo 26.09.2021 aktualisiert um 12:36:13 Uhr
Goto Top
Servus Peter.
Zu aller erst, die Dateiversion bekommt man zuverlässiger und ohne langwierige Schleife anhand der CLSID der Windows-Property und der Methode ExtendedProperty über Windows OS hinweg sprachunabhängig. Das kennt aber leider kaum einer.

Dann zu der Meldung die du erhältst: Die Meldung kommt wenn du in den Kontextmenüeintrag den VBS Pfad direkt einträgst, damit kann Windows hier nichts anfangen, du musst das VBS Skript dort stattdessen explizit mit dem regulären Interpreter wscript.exe oder cscript.exe starten und den Pfad des Skripts übergeben:
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\RenameWithVersion\command]
@="wscript \"C:\\PfadZumScript\\rename_with_version.vbs\" \"%1\""  
Und als Hinweis wie man das Auslesen der Property effektiver und auch Sprachunabhänig macht (Zeile 16)
Dim arg, folder, fso, objShell, bname, ext, destination, fileversion
Set fso = CreateObject("Scripting.FileSystemObject")  
Set objShell = CreateObject("Shell.Application")  

If WScript.Arguments.Count > 0 Then
	arg = WScript.Arguments(0)
Else
	MsgBox "Keine Datei übergeben!",vbExclamation  
	WScript.Quit 1
End If

If fso.FileExists(arg) Then
	folder = fso.GetParentFolderName(arg)
	bname = fso.GetBaseName(arg)
	ext = fso.GetExtensionName(arg)
	fileversion = objShell.NameSpace(folder).ParseName(fso.GetFileName(arg)).ExtendedProperty("{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 4")  
	If fileversion <> "" Then  
		destination = folder & "\" & bname & "." & fileversion & "." & ext  
		fso.MoveFile arg, destination
	Else
		MsgBox "Version ist leer!",vbExclamation  
	End If
Else
	MsgBox "Datei '" & arg & "' existiert nicht.", vbExclamation  
	WScript.Quit 1
End If

Brauchst du stattdessen die ProductVersion statt die FileVersion (die können sich ja je nach Produkt unterscheiden) machst du das am Ende von Zeile 16 meines Skriptes einfach so
.ExtendedProperty("System.Software.ProductVersion")
Das Äquivalent für die CLSID für "FileVersion" im Klartext ist
.ExtendedProperty("System.FileVersion")

Ich habe in meinem Beispiel die CLSID und die propID verwendet weil das etwas effektiver ist als mit den Namen zu arbeiten.

Grüße Uwe
Mitglied: PeterleB
PeterleB 26.09.2021 um 12:46:25 Uhr
Goto Top
Hallo,

lieber Uwe, Du bist wieder mal der Beste!
Abgesehen von einem fehlenden Backslash in meiner Version funktioniert es jetzt hervorragend.
Deine Erläuterungen überzeugen mich und ich werde deshalb Deine Variante einsetzen.
Habe noch ein //NOLOGO in den Registryeintrag eingefügt.
Vielen Dank.

Zu Testzwecken habe ich versucht, das gleiche Problem mit Powershell anzugehen.
Hätte das Vorteile?

<#
Rename-Files.ps1
Nach einer Idee von: Don Jones: "Appending text to a variable file name"   
https://powershell.org/forums/topic/appending-text-to-the-beginning-of-a-variable-file-name/
#>
param(
    [string]$file
)

# Inserting file version into filename

        $source_file = (Get-Item $file).FullName
        $source_onlyname = (Get-Item $file).BaseName # ohne Erweiterung
        $source_path = (Get-Item $file).DirectoryName # nur Pfad
        $source_ext = (Get-Item $file).Extension
        $version = (Get-Item $file).VersionInfo.FileVersion

                $old_file_name = $fsource_file
                $new_full_name = "$($source_path)" + "\" + "$($source_onlyname)" + "." + "$($version)" + "$($source_ext)"  

                # Rename the file (perhaps first with the -WhatIf parameter?)
                # Rename-Item $source_file -NewName $new_full_name -WhatIf
                [System.Windows.Forms.MessageBox]::Show($new_full_name,"Version",0)  
                Rename-Item $source_file -NewName $new_full_name
# 

Was hältst Du davon?

Gruß
Peter
Mitglied: colinardo
colinardo 26.09.2021 aktualisiert um 13:18:57 Uhr
Goto Top
Zitat von @PeterleB:
Habe noch ein NOLOGO in den Registryeintrag eingefügt.
Kannst du machen ist aber überflüssig. VBS zeigt via wscript per default keine Interpreter-Banner.
Zu Testzwecken habe ich versucht, das gleiche Problem mit Powershell anzugehen.
Hätte das Vorteile?
Was hältst Du davon?
Sicher kannst du auch zur Powershell greifen, das ist dann jedem selbst überlassen, du musst halt die Executionpolicy beachten des jeweiligen Systems beachten z.B. über -EP Bypass im Kontextmenüeintrag.
Und auch das aufblitzende Powershell-Fenster das du zwar mit -WindowStyle hidden etwas aber nicht ganz abstellen kannst. Für vollständige Unsichbarkeit ist dann wieder der Aufruf über ein wrapper vbs mit wscript.shell nötig.

p.s. das doppelt und dreifachen Aufruf get-item solltest du besser über eine Variable ablösen das kostet nur unnötige Ressourcen wenn das System die Properties immer erst erneut abfragen muss.

Das ganze lässt sich dann auch auf folgendes Powershell-Script reduzieren:
param(
    [parameter(mandatory=$true)][ValidateScript({Test-Path $_})][string]$file
)
Get-Item -LiteralPath $file | rename-item -NewName {"$($_.BaseName).$($_.VersionInfo.FileVersion)$($_.Extension)"} -verbose  
Mitglied: PeterleB
PeterleB 26.09.2021 um 13:34:52 Uhr
Goto Top
Hallo,

hab noch ein Icon für den Menüeintrag gefunden, dann sieht die Reg-Datei so aus:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\exefile\shell\RenameWithVersion]
"Icon"="imageres.dll,89"  
@="Version in Name übernehmen"  

[HKEY_CLASSES_ROOT\exefile\shell\RenameWithVersion\command]
@="wscript //NOLOGO \"C:\\Scripts\\rename_with_version.vbs\" \"%1\""  

Gruß
Peter
Mitglied: PeterleB
PeterleB 26.09.2021 um 13:52:31 Uhr
Goto Top
Nochmals vielen Dank.
Habe Deinen Beitrag als Lösung markiert.

Gruß
Peter