INSERT INTO funktioniert nicht
Guten Abend liebe Kolleginnen und Kollegen,
ich gehe - wieder einmal - einer meiner Entwicklungen nach, welche ich mal angefangen habe.
Es geht darum in der Tabelle Property einer MSI-Datei eine Zeile mit Hilfe von Powershell hinzuzufügen.
Nachstehend mein aktuellen Entwurf:
Die Fehlermeldung lautet wie folgt:
Kommentiere ich die Zeile 9 ein und die Zeile 10 (INSERT INTO gegen SELECT) funktioniert die Abfrage problemlos.
Leider verstehe ich nach Stunden des Lesen nichts, was mein Fehler ist. Kann mir jemand auf die Sprünge helfen?
Gruß,
Dani
ich gehe - wieder einmal - einer meiner Entwicklungen nach, welche ich mal angefangen habe.
Es geht darum in der Tabelle Property einer MSI-Datei eine Zeile mit Hilfe von Powershell hinzuzufügen.
Nachstehend mein aktuellen Entwurf:
# Add Required Type Libraries
Add-Type -Path "C:\Temp\abc\Microsoft.Deployment.WindowsInstaller.dll"
# Open an MSI Database
$oDatabase = New-Object Microsoft.Deployment.WindowsInstaller.Database("C:\Temp\abc\German.msi", [Microsoft.Deployment.WindowsInstaller.DatabaseOpenMode]::Direct);
Write-Host "Create a Select Query for individual property"
#$sSQLQuery = "SELECT * FROM Property WHERE Property= 'ProductCode'"
$sSQLQuery = "INSERT INTO Property (Property, Value) VALUES ('abc', 'def')"
Write-Host "Create and Execute a View object"
[Microsoft.Deployment.WindowsInstaller.View]$oView = $oDatabase.OpenView($sSQLQuery)
$oView.Execute()
$oDatabase.Commit()
$oView.Close();
$oDatabase.Dispose();
PS C:\Temp\abc> C:\Temp\abc\Unbenannt1.ps1
Create a Select Query for individual property
Create and Execute a View object
Ausnahme beim Aufrufen von "Execute" mit 0 Argument(en): "Beim Ausführen der Funktion ist ein Fehler aufgetreten."
In C:\Temp\abc\Unbenannt1.ps1:14 Zeichen:1
+ $oView.Execute()
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) , MethodInvocationException
+ FullyQualifiedErrorId : InstallerException
PS C:\Temp\abc>
Leider verstehe ich nach Stunden des Lesen nichts, was mein Fehler ist. Kann mir jemand auf die Sprünge helfen?
Gruß,
Dani
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 392418
Url: https://administrator.de/contentid/392418
Ausgedruckt am: 23.11.2024 um 14:11 Uhr
9 Kommentare
Neuester Kommentar
Moin,
Habe selbst damit noch nicht gearbeiteit, aber ein schnelles googeln zeigte dort, dass vor deiner Variable $sSQLQuery evtl. noch ein [string] platziert werden sollte...
Versuch macht kluch...
Gruß
em-pie
Habe selbst damit noch nicht gearbeiteit, aber ein schnelles googeln zeigte dort, dass vor deiner Variable $sSQLQuery evtl. noch ein [string] platziert werden sollte...
Versuch macht kluch...
Gruß
em-pie
'n Abend,
die von @em-pie angegebene Quelle macht beim Beispiel für
Entscheidend ist der zweite Punkt.
Grüße
Friemler
die von @em-pie angegebene Quelle macht beim Beispiel für
Inserting a New Record
folgende Aussage:Trial and error has shown a couple of quirks with PowerShell and using “INSERT INTO” sql.
- It only works with Direct DatabaseOpenMode methods – not Transact.
- SQL must be passed to the oDatabase .Execute and will not work when used with a “View,Execute”
Entscheidend ist der zweite Punkt.
Grüße
Friemler
Hallo Dani,
wenn man alle möglichen Dinge ausprobiert hat und zu keinem Erfolg kam, sollte man anfangen die unmöglichen Dinge auszuprobieren.
Zumindest ab der dritten Ebene der Klassenhierarchie sind die beiden Bibliotheken identisch, evtl. haben sie auch die gleichen Macken.
Just my 2 cents.
Grüße
Friemler
wenn man alle möglichen Dinge ausprobiert hat und zu keinem Erfolg kam, sollte man anfangen die unmöglichen Dinge auszuprobieren.
Zumindest ab der dritten Ebene der Klassenhierarchie sind die beiden Bibliotheken identisch, evtl. haben sie auch die gleichen Macken.
Just my 2 cents.
Grüße
Friemler
Servus Dani,
Wie gesagt das war ein rudimentäres Basis-Beispiel, bei anderen Methoden wie ReadStream etc. sind je nach Methode erweiterte Konstruktoren für InvokeMember nötig. Etwas Background.
Grüße Uwe
p.s. solltest du das in der ISE testen und die MSI nach Anwendung eventuell noch gesperrt sein liegt das an noch offenen Handles der ISE auf das MSI File. Sollte zwar mit obigem Cleaning der Ressourcen nicht auftreten, kann aber je nach OS unter Umständen beim Testen vorkommen. In dem Fall die ISE schließen um das MSI File frei zu geben.
Inzwischen habe ich folgenden Schnipsel auf Basis von VBScript gefunden.
mit dem "integrierten Windows Installer Com-Object" geht das auch in Powershell ohne weitere DLL, nur muss man hier etwas in die Trickkiste greifen da die Methoden dem COM-Objekt in der PS nicht automatisch hinzugefügt werden weil die TypeLibs fehlen, das heißt man muss sie selbst manuell über InvokeMember aufrufen. Rudimentäres Beispiel mit Kommentaren ohne erweitertes Error-Handling für die Übersicht.# MSI File
$msifile ='C:\Temp\abc\German.msi'
# SQL Query
$query = "INSERT INTO Property (Property, Value) VALUES ('abc', 'def')"
# Installer Com Object erstellen
$wi = New-Object -ComObject WindowsInstaller.Installer
# Skriptblock der Methoden im COM-Object passend aufruft
$im = {$this.gettype().invokeMember($args,[System.Reflection.BindingFlags]::InvokeMethod,$null,$this,$args[1..($args.count -1)])}
# InvokeMethod Funktion dem Installer Object hinzufügen
$wi = $wi | Add-Member -MemberType ScriptMethod -Value $im -Name InvokeMethod -PassThru
# OpenDatabase Methode mit Pfad und OpenMode (2) aufrufen
$db = $wi.InvokeMethod("OpenDatabase",$msifile,2)
# InvokeMethod Funktion dem Database Object hinzufügen
$db = $db | Add-Member -MemberType ScriptMethod -Value $im -Name InvokeMethod -PassThru
# OpenView Methode mit SQL query aufrufen
$view = $db.InvokeMethod("OpenView",$query)
# InvokeMethod Funktion dem View Object hinzufügen
$view = $view | Add-Member -MemberType ScriptMethod -Value $im -Name InvokeMethod -PassThru
# Execute view
$view.InvokeMethod("Execute")
# Close view
$view.InvokeMethod("Close")
# Commit database
$db.InvokeMethod("Commit")
# cleanup
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($db)
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($view)
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($wi)
Grüße Uwe
p.s. solltest du das in der ISE testen und die MSI nach Anwendung eventuell noch gesperrt sein liegt das an noch offenen Handles der ISE auf das MSI File. Sollte zwar mit obigem Cleaning der Ressourcen nicht auftreten, kann aber je nach OS unter Umständen beim Testen vorkommen. In dem Fall die ISE schließen um das MSI File frei zu geben.