Fehler bei COM abfrage

  • Hi,
    ich habe ein Problem bei einer COM Abfrage.
    Ich versuche zu einer Datei einen Kommentar hinzuzufügen, aber ich bekomme schon beim öffnen ein Problem.
    Ich habe nicht sehr viel ahnung von COM, daher habe ich mich an ein VB Script gehalten und habe versucht das in AutoIt zu übersetzen.

    VB Script:

    Code
    Set oFile = CreateObject("DSOFile.OleDocumentProperties")
    oFile.Open("c:\tmp\test.txt")
    oFile.SummaryProperties.Comments = "Test Comment"
    oFile.Save
    oFile.Close

    Mein Script:

    [autoit]


    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    [/autoit][autoit][/autoit][autoit]

    $oFile = ObjCreate("DSOFile.OleDocumentProperties")
    If Not @error Then
    ;~ MsgBox(4096, "ObjCreate Test", "ObjCreate() of a DSO File Object successful !")
    $oFile.Open("C:\neu.docx")
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.SummaryProperties.Comments = "Test Kommentar"
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Save
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Close
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    Else
    MsgBox(4096, "ObjCreate Test", "Failed to create Object. Error code: " & Hex(@error, 8))
    EndIf
    Exit

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _ErrFunc($oError)
    ConsoleWrite("err.number is: " & @TAB & $oError.number & @CRLF & _
    "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
    "err.description is: " & @TAB & $oError.description & @CRLF & _
    "err.source is: " & @TAB & $oError.source & @CRLF & _
    "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
    "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
    "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    EndFunc ;==>_ErrFunc

    [/autoit]

    Ich bekomme immer schon beim oFile.Open einen Fehler rausgeworfen:

    err.number is: -2147352567
    err.windescription: Unbekannter Fehler
    err.description is:
    err.source is: Dsofile.dll
    err.helpfile is:
    err.helpcontext is: 0
    err.lastdllerror is: 0
    err.scriptline is: 19
    err.retcode is: -2147467259


    Weiss jemand was ich falsch mache?

    Hinweis: Man benötigt Dsofile.dll von Microsoft, welche dann per regsvr32 registriert werden muss. http://support.microsoft.com/kb/224351/EN-US

    EDIT:
    Ich habe jetzt nochmal getestet ob es eventuell an der registrierten DLL liegt und habe eine alternative Methode probiert ohne die DLL zu registrieren, führt aber zum selben fehler, also liegt es vermutlich an meinem Code.

    Alternative Methode:

    [autoit]


    ; Object identifiers
    Global Const $sCLSID_OleDocumentProperties = "{58968145-CF05-4341-995F-2EE093F6ABA3}"
    Global Const $IID_OleDocumentProperties = "{58968145-CF01-4341-995F-2EE093F6ABA3}"
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $sDll = "dsofile.dll" ; location and name of your dll
    $hDll = DllOpen($sDll) ; open it

    [/autoit][autoit][/autoit][autoit]

    ; Experimenal feature. Try with newer versions of AutoIt
    $oFile = ObjCreate($sCLSID_OleDocumentProperties, $IID_OleDocumentProperties, $hDll)
    If Not @error Then
    ;~ MsgBox(4096, "ObjCreate Test", "ObjCreate() of a DSO File Object successful !")
    $oFile.Open("C:\neu.docx")
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.SummaryProperties.Comments = "Test Kommentar"
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Save
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Close
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    Else
    MsgBox(4096, "ObjCreate Test", "Failed to create Object. Error code: " & Hex(@error, 8))
    EndIf
    DllClose ($hDll)
    Exit

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _ErrFunc($oError)
    ConsoleWrite("err.number is: " & @TAB & $oError.number & @CRLF & _
    "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
    "err.description is: " & @TAB & $oError.description & @CRLF & _
    "err.source is: " & @TAB & $oError.source & @CRLF & _
    "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
    "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
    "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    EndFunc ;==>_ErrFunc

    [/autoit]

    2 Mal editiert, zuletzt von Neklor (23. März 2013 um 00:31)

  • ...ist es Dein Ziel die Dokumenteneigenschaften einer .docx (Word) Datei auszulesen bzw zu setzen?

    Dann empfehle ich Dir das Word-UDF und darin die Funktion _WordDocPropertyGet bzw. _WordDocPropertySet (Auszug aus der Hilfe im Spoiler)

    Deine og. Fehlermeldungen würde ich dahingehend interpretieren, dass die DLL keine Worddateien verarbeiten kann.

    Spoiler anzeigen


    Funktionsreferenz

    --------------------------------------------------------------------------------

    _WordDocPropertyGet
    Gibt eine ausgewählte Eigenschaft der Word-Datei zurück.


    #include <Word.au3>
    _WordDocPropertyGet(ByRef $o_object, $v_property)


    Parameter
    $o_object Objektvariable eines Word.Application Dokumentobjekts.
    $v_property gewählte Eigenschaft (siehe Bemerkungen)

    Rückgabewert
    Erfolg: Wert der ausgewählten Eigenschaft
    Fehler: Gibt 0 zurück und setzt @ERROR
    @Error: $_WordStatus_Success = Kein Fehler
    $_WordStatus_GeneralError = allgemeiner Fehler
    $_WordStatus_ComError = Com Fehler
    $_WordStatus_InvalidDataType = ungültiger Datentyp
    $_WordStatus_InvalidObjectType = ungültiger Objekttyp
    $_WordStatus_InvalidValue = ungültiger Wert
    @Extended: Nummer des ungültigen Parameters

    Bemerkungen
    Man kann entweder den Index oder Namen für die Auswahl der Eigenschaft verwenden.

    Die folgenden Tabellen zeigen eine Beschreibung für jede verfügbare Eigenschaft.

    Word Dokument Eigenschaften

    Index der Eigenschaft/Name Beschreibung
    (1) "title" Titel.
    (2) "subject" Thema.
    (3) "author" Autor.
    (4) "keywords" Stichwörter.
    (5) "comments" Kommentare.
    (6) "template" Name der Vorlage.
    (7) "last author" Letzter Autor.
    (8 ) "revision number" Anzahl der Überarbeitungen.
    (9) "application name" Name der Anwendung.
    (10) "last print date" letztes Druckdatum.
    (11) "creation date" Erstelldatum.
    (12) "last save time" zuletzt gespeichert am.
    (13) "total editing time" Anzahl von Änderungen im VBA Pojekt.
    (14) "pages" Anzahl Seiten.
    (15) "words" Anzahl Wörter.
    (16) "characters" Anzahl Zeichen.
    (17) "security" Sicherheitseinstellungen.
    (18 ) "category" Kategorie.
    (19) "" nicht unterstützt.
    (20) "manager" Manager.
    (21) "company" Firma.
    (22) "bytes" Anzahl Bytes.
    (23) "lines" Anzahl Zeilen.
    (24) "paragraphs" Anzahl Absätze.
    (25-28 ) "" nicht unterstützt.
    (29) "hyperlink base" Wenn ein relativer Link auf einem festgelegten Pfad basiert (der erste Teil des Pfades der Datei, der den Hyperlink und die Zieldatei enthält), ist der Pfad die Basis des Hyperlinks.
    (30) "characters (with spaces)" Anzahl Zeichen inkl. Leerzeichen.


    Verwandte Funktionen
    _WordDocPropertySet
    Beispiel

    ; *******************************************************
    ; Beispiel 1 - Erstellt ein Word-Fenster, öffnet ein Dokument
    ; und liest alle verfügbaren Dokumenteigenschaften durch den Index.
    ; *******************************************************
    ;
    #include <Word.au3>

    Local $oWordApp = _WordCreate(@ScriptDir & "\Test.doc")
    Local $oDoc = _WordDocGetCollection($oWordApp, 0)
    For $i = 1 To 30
    ConsoleWrite("Index der Eigenschaft " & $i & " - " & _WordDocPropertyGet($oDoc, $i) & @CR)
    Next

    ; *******************************************************
    ; Beispiel 2 - Erstellt ein Word-Fenster, öffnet ein Dokument
    ; und liest den Titel, Betreff und Autor des Dokumentes durch den Namen aus.
    ; *******************************************************
    ;
    #include <Word.au3>
    $oWordApp = _WordCreate(@ScriptDir & "\Test.doc")
    $oDoc = _WordDocGetCollection($oWordApp, 0)
    ConsoleWrite("Titel - " & _WordDocPropertyGet($oDoc, "Title") & @CRLF)
    ConsoleWrite("Betreff - " & _WordDocPropertyGet($oDoc, "Subject") & @CRLF)
    ConsoleWrite("Autor - " & _WordDocPropertyGet($oDoc, "Author") & @CRLF)

    Einmal editiert, zuletzt von qwert23 (23. März 2013 um 13:29)


  • Grundsätzlich suche ich eine möglichkeit den kommentar bei so ziemlich jedem Dateityp zu setzen odert alternativ wenn das nicht geht eine eigene Eigenschaft hinzuzufügen.
    Diese DLL soll das zumindest schonmal bei allen Office dokumenten ermöglichen, was ja schonmal ganz gut ist. Eventuell kann man damit sogar alle Dateitypen bearbeiten.
    .docx kann die DLL laut Microsoft. Ich weiss das, dass Objekt erfolgreich erstellt wird, nur der Code danach verursacht Fehler...

    Gibt es vieleicht irgendeine Standard Funktion, die das auch kann? Ansonsten, weiss jemand, was hier nicht funktioniert?

  • Also ich verstehe die bisher gegebenen Infos so:

    • DSOFile.dll gibt Dir die Möglichkeit Attribute von Office Dokumenten zu ändern auch wenn Office gar nicht installiert ist
    • Wenn Office installiert ist, danna geht das auch mit Funktionen aus der Word UDF oder direkt über COM
    • Mit DSOFile lassen sich Properties anderer Dateitypen nicht ändern
    • Dazu gibt es garantiert eine Windows API
  • Also ich verstehe die bisher gegebenen Infos so:

    • DSOFile.dll gibt Dir die Möglichkeit Attribute von Office Dokumenten zu ändern auch wenn Office gar nicht installiert ist
    • Wenn Office installiert ist, danna geht das auch mit Funktionen aus der Word UDF oder direkt über COM
    • Mit DSOFile lassen sich Properties anderer Dateitypen nicht ändern
    • Dazu gibt es garantiert eine Windows API


    So ist es ;)
    Aber eine Windows API konnte ich dazu bisher noch nicht finden. Also wenn jemand mehr zu dem Thema weiss, ich bin für jede Hilfe dankbar :)

  • So,
    nach einigem getüfftel habe ich rausgefunden woran es lag. Offenbar am docx Format.
    Aber eigentlich sollte doch genau das damit gehen oder?

    Folgendes funktioniert wunderbar:

    [autoit]


    ; Object identifiers
    Global Const $sCLSID_OleDocumentProperties = "{58968145-CF05-4341-995F-2EE093F6ABA3}"
    Global Const $IID_OleDocumentProperties = "{58968145-CF01-4341-995F-2EE093F6ABA3}"
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $sDll = "dsofile.dll" ; location and name of your dll
    $hDll = DllOpen($sDll) ; open it

    [/autoit][autoit][/autoit][autoit]

    ; Experimenal feature. Try with newer versions of AutoIt
    $oFile = ObjCreate($sCLSID_OleDocumentProperties, $IID_OleDocumentProperties, $hDll)
    If Not @error Then
    ;~ MsgBox(4096, "ObjCreate Test", "ObjCreate() of a DSO File Object successful !")
    $oFile.Open("D:\neu.doc")
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.SummaryProperties.author = "Das ist ein Test Autor"
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Save
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Close
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    Else
    MsgBox(4096, "ObjCreate Test", "Failed to create Object. Error code: " & Hex(@error, 8))
    EndIf
    DllClose ($hDll)
    Exit

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _ErrFunc($oError)
    ConsoleWrite("err.number is: " & @TAB & $oError.number & @CRLF & _
    "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
    "err.description is: " & @TAB & $oError.description & @CRLF & _
    "err.source is: " & @TAB & $oError.source & @CRLF & _
    "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
    "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
    "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    EndFunc ;==>_ErrFunc

    [/autoit]

    Damit bleiben aber leider einige Probleme offen:
    1. Warum geht das nicht mit .docx (Ich habe irgendow in der Beschreibung von MS gelesen, dass das jetzt supported wird. Gelöst
    2. Ich brauche die Funktion $oFile.CustomProperties.Add, kriege die aber nicht zum laufen. In C# würde man die wohl so aufrufen: oFile.CustomProperties.Add Test, Wert

    Kann da jemand weiter helfen?

    Ich habe, die DLL jetzt mal angehängt, der Download von Microsoft ist ja doch etwas umständlich, weil da soviel anderer kram mit drinne ist.

    autoit.de/wcf/attachment/20067/

  • Manchmal ist die Lösung ziemlich einfach...
    Ich versuche es die ganze Zeit mit neu erstellten leeren Dokumenten...
    Ein Buchstabe im Dokument reicht und schon funktioniert es auch mit .docx :D
    Das 2. Problem besteht aber weiterhin.

  • Hi,
    das 2. Problem bleibt!
    Aber ich möchte hier schonmal einige Erkenntnisse mitteilen, die vieleicht dem einen oder anderem mit dem selben Problem, helfen könnten.
    Ich habe jetzt etwas mit verschiedenen Dateitypen experimentiert.
    Offenbar kann man mit der dsofile.dll so ziemlich alle Dateitypen bearbeiten.
    Nachteil: Ändert man den Autor bei einem .txt File oder einer Avi Datei, wo es diesen ja gar nicht gibt, so kann das vom Explorer nicht angezeigt werden.
    Vorteil: Der Wert ist aber trotzdem da, d.h. ich kann ihn mit einem Script auch wieder auslesen.

    Hier einmal die ein Beispiel an einer Avi Datei:

    Wert setzen:

    [autoit]

    ; Object identifiers
    Global Const $sCLSID_OleDocumentProperties = "{58968145-CF05-4341-995F-2EE093F6ABA3}"
    Global Const $IID_OleDocumentProperties = "{58968145-CF01-4341-995F-2EE093F6ABA3}"
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    $sDll = "dsofile.dll" ; location and name of your dll
    $hDll = DllOpen($sDll) ; open it

    [/autoit][autoit][/autoit][autoit]

    ; Experimenal feature. Try with newer versions of AutoIt
    $oFile = ObjCreate($sCLSID_OleDocumentProperties, $IID_OleDocumentProperties, $hDll)
    If Not @error Then
    ;~ MsgBox(4096, "ObjCreate Test", "ObjCreate() of a DSO File Object successful !")
    $oFile.Open("D:\ScreenRecords\Test.avi")
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.SummaryProperties.author = "Das ist ein Test Autor 124"
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Save
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Close
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    Else
    MsgBox(4096, "ObjCreate Test", "Failed to create Object. Error code: " & Hex(@error, 8))
    EndIf
    DllClose ($hDll)
    Exit

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _ErrFunc($oError)
    ConsoleWrite("err.number is: " & @TAB & $oError.number & @CRLF & _
    "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
    "err.description is: " & @TAB & $oError.description & @CRLF & _
    "err.source is: " & @TAB & $oError.source & @CRLF & _
    "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
    "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
    "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    EndFunc ;==>_ErrFunc

    [/autoit]

    Und so liest man es wieder aus:

    [autoit]

    ; Object identifiers
    Global Const $sCLSID_OleDocumentProperties = "{58968145-CF05-4341-995F-2EE093F6ABA3}"
    Global Const $IID_OleDocumentProperties = "{58968145-CF01-4341-995F-2EE093F6ABA3}"
    Local $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")
    Dim $test

    [/autoit][autoit][/autoit][autoit]

    $sDll = "dsofile.dll" ; location and name of your dll
    $hDll = DllOpen($sDll) ; open it

    [/autoit][autoit][/autoit][autoit]

    ; Experimenal feature. Try with newer versions of AutoIt
    $oFile = ObjCreate($sCLSID_OleDocumentProperties, $IID_OleDocumentProperties, $hDll)
    If Not @error Then
    ;~ MsgBox(4096, "ObjCreate Test", "ObjCreate() of a DSO File Object successful !")
    $oFile.Open("D:\ScreenRecords\Test.avi")
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    MsgBox(0, "Test", $oFile.SummaryProperties.author)
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    $oFile.Close
    If @error Then MsgBox(48 + 262144, "COM Error", "@error is set to COM error number." & @CRLF & "@error = " & @error)
    Else
    MsgBox(4096, "ObjCreate Test", "Failed to create Object. Error code: " & Hex(@error, 8))
    EndIf
    DllClose ($hDll)
    Exit

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _ErrFunc($oError)
    ConsoleWrite("err.number is: " & @TAB & $oError.number & @CRLF & _
    "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
    "err.description is: " & @TAB & $oError.description & @CRLF & _
    "err.source is: " & @TAB & $oError.source & @CRLF & _
    "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
    "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
    "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    EndFunc ;==>_ErrFunc

    [/autoit]