dani
Goto Top

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:
# 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();
Die Fehlermeldung lautet wie folgt:
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>
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

Content-ID: 392418

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

Ausgedruckt am: 23.11.2024 um 14:11 Uhr

em-pie
em-pie 11.11.2018 um 22:50:19 Uhr
Goto Top
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
Dani
Dani 11.11.2018 um 23:05:50 Uhr
Goto Top
Guten Abend @em-pie,
du hast gesehen, dass dort eine andere Bibliothek benutzt wird? face-smile
Unabhängig davon habe ich einmal den Typ [string] angegeben. Leider ändert sich nichts am Verhalten bzw. Fehlermeldung.


Gruß,
Dani
Friemler
Friemler 12.11.2018 um 01:36:19 Uhr
Goto Top
'n Abend,

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
Dani
Dani 12.11.2018 aktualisiert um 16:47:35 Uhr
Goto Top
Hallo Friemler,
Entscheidend ist der zweite Punkt.
wie gesagt, dort wird eine andere Bibliothek verwende.


Inzwischen habe ich folgenden Schnipsel auf Basis von VBScript gefunden.
Set installer = CreateObject("WindowsInstaller.Installer")  
Set database = installer.OpenDatabase ("C:\Temp\abc\German.msi", 1)  
 
' Add (Insert)  
Set view = database.OpenView ("INSERT INTO Property (Property, Value) VALUES ('abc', 'def')")  
 
view.Execute()
database.Commit()
Das Skript funktioniert/macht was es soll.
Wenn ich nun mein Versuch darüber lege, stimmt die Struktur (Query -> View -> Exec -> Commit) eigentlich.


Gruß,
Dani
Friemler
Friemler 12.11.2018 um 17:07:22 Uhr
Goto Top
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
colinardo
Lösung colinardo 12.11.2018 aktualisiert um 19:07:54 Uhr
Goto Top
Servus Dani,
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)
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.
Dani
Dani 12.11.2018, aktualisiert am 13.11.2018 um 20:57:06 Uhr
Goto Top
Guten Abend Uwe,
erst einmal vielen Dank für das Skript - wie immer Tip Top!

Klar, wieso bin ich nicht gleich darauf gekommen. face-wink Spaß bei Seite. Das ist mir deutlich 1-2 Gedankengänge zu hoch. Ich werde mich mit der VBScript Variante intensiver auseinander setzen.

Dieser be*** Arbeitsbeschaffungsmaßnahme habe ich nur an der Backe, weil eine Anstalt des Bundes nicht in der Lage ist saubere MSI Dateien zu erstellen. Bereits in der Vergangenheit mehrmals daraufhin gewiesen, dass eine Verteilung so nicht möglich ist. Abhilfe ist bis heute nicht in Sicht, obwohl es nur 3-4 Korrekturen sind. *kopfschüttel*

Mal schauen, ob wir uns den Spaß gönnen und denen nach Abschluss der Arbeitsbeschaffungsmaßnahme eine Rechnung schicken. face-smile


Gruß,
Dani
colinardo
colinardo 13.11.2018, aktualisiert am 14.11.2018 um 11:04:26 Uhr
Goto Top
weil eine Anstalt des Bundes nicht in der Lage ist saubere MSI Dateien zu erstellen
Eine "Anstalt" halt face-smile.

Mein Mitgefühl hast du, ich glaube da macht fast jeder die selben Erfahrungen, ich zumindest auch. Unflexibel hoch drei, Dienst nach Vorschrift usw.
Dani
Dani 19.11.2018, aktualisiert am 14.01.2019 um 18:38:04 Uhr
Goto Top
Hallo zusammen,
ich habe das Ganze über ein VBScript nun gelöst bekommen. Select, Update, Insert Into funktioniert unter VBScript völlig problemlos.

Mein Mitgefühl hast du, ich glaube da macht fast jeder die selben Erfahrungen, ich zumindest auch. Unflexibel hoch drei, Dienst nach Vorschrift usw.
Wenn ich nicht wüsste, dass das gelernte IT-Admins sind, welche auch noch mehr verdienen als ich, wäre es mir fast egal. Aber so, bekomme ich ein hohen Puls!


Gruß,
Dani