none
COM error 0x800A175D opening specific .doc file RRS feed

  • Question

  • Using the code below to open a word document.  It's worked successfully on several thousand documents, but my customer recently sent me one that causes an automation error during the call to Documents.Open();  Error is "Could not open macro storage."

    I've searched and see a lot about normal.dot being corrupt, or an unspecified user context, however in my case:

    1. It fails only on specific document(s)
    2. Application is a desktop application running as the interactive user.
    3. Task manager shows word also running as interactive user (in same session).
    4. If word is launched manually, the document opens without any complaint.

    So is there anything else I can try?

    ts.TraceEvent(TraceEventType.Verbose, 0, "new Word.Application();");
    word = new Application();
    word.Visible = visible;
    
    ts.TraceEvent(TraceEventType.Verbose, 0, "word.Documents.Open(\"{0}\");", fileName);
    document = word.Documents.Open(ref oFileName, // FileName
                    ref oFalse,  // ConfirmConversions (false=no dialog)
                    ref oFalse,  // ReadOnly
                    ref oFalse,  // AddToRecentFiles
                    ref oMissing, // PasswordDocument
                    ref oMissing, // PasswordTemplate
                    ref oMissing, // Revert
                    ref oMissing, // WritePasswordDocument
                    ref oMissing, // WritePasswordTemplate
                    ref oMissing, // Format
                    ref oMissing, // Encoding
          /*
          ** passing oFalse for Visible here causes an exception 
          ** when the document is printed. Rely on oMissing to 
          ** grab the correct value from the application state.
          */
                    ref oMissing, // Visible
                    ref oFalse,  // OpenAndRepair (false=no dialog)
                    ref oMissing, // DocumentDirection
                    ref oTrue,   // NoEncodingDialog
                    ref oMissing); // XMLTransform
    
    if (null == document)
      throw new Exception("No document after successful open.");
    

    This signature unintentionally left blank.
    Monday, April 25, 2011 12:18 PM

All replies

  • Hi Nick

    Which version of Word is involved and, is the file in question one created in this version, or a different one? If different, which version?

    If you passing "Missing" for all parameters except filename, does that make any difference?

    FWIW my first reaction when I started reading your message was that this particular document is damaged. And that could well be the case... But it would be interesting to track down why opening it manually doesn't display the message. I'm wondering if it's because you set OpenAndRepair to false?


    Cindy Meister, VSTO/Word MVP
    Monday, April 25, 2011 5:33 PM
    Moderator
  • Hi Cindy,

    I've duplicated the problem in:

    • Word 2010 x64 on Windows 7 x64 from x64 app.
    • Word 2007 x86 on Server 2003 R2 x86 from x86 app.

    Both systems have all updates as of a few days ago.  Changing all parameters to oMissing doesn't make a difference for this error. 

    As I said, If I open the document from the Word GUI (even if I open it using the winword.exe instance started via automation) it opens without complaint, dialog, warning or hiccup. 

    I do not know what version of Word created the document, only that it is in .DOC format.  The only thing that appears different about this document is that it references two add-in's or macros that definitely do not exist in my dev environment(s) and may not exist on customer(s).  And while it looks different when compared to my other samples, I can't really say with 100% certanty that it's different than everything else the customer has processed thus far.

     


    This signature unintentionally left blank.
    Monday, April 25, 2011 6:46 PM
  • << The only thing that appears different about this document is that it references two add-in's or macros that definitely do not exist in my dev environment(s) and may not exist on customer(s).

    >>

    That's probably enough to raise this error, although you might hope that you would get something slightly more friendly such as "could not locate the referenced macro or its container"

    AIUI all "could not open macro storage" is really telling you is that VBA is looking for a particular structured storage file such as a .DOT or .DOC, and looking for the storage within that file that contains the VBA code. If it can't open it, that could be because

     a. the container (the .doc/.dot) isn't there

     b. the container cannot be opened with the caller's permissions

     c. the container is there but the storage isn't there (e.g. on your system you have a container with the expected name, but it contains no macros)

     d. the container is there and the storage is there but cannot be opened with the caller's permissions

    I don't know in what circumstances you might encounter (d), but (a), (b) and (c) sound as if they might occur fairly easily.


    Peter Jamieson
    Monday, April 25, 2011 7:06 PM
  • Peter,

    Thanks that makes sense, and lead to the discovery that the document is in fact being opened.  So here's where I am now.  So far nothing I've done to try and get the document reference (even though I can see it's open) has been successful. 

    ts.TraceEvent(TraceEventType.Verbose, 0, "word.Documents.Open(\"{0}\");", fileName);
    try
    {
      document = word.Documents.Open(ref oFileName, // FileName
                      ref oFalse,  // ConfirmConversions (false=no dialog)
                      ref oFalse,  // ReadOnly
                      ref oFalse,  // AddToRecentFiles
                      ref oMissing, // PasswordDocument
                      ref oMissing, // PasswordTemplate
                      ref oMissing, // Revert
                      ref oMissing, // WritePasswordDocument
                      ref oMissing, // WritePasswordTemplate
                      ref oMissing, // Format
                      ref oMissing, // Encoding
        /*
        ** passing oFalse for Visible here causes an exception 
        ** when the document is printed. Rely on oMissing to 
        ** grab the correct value from the application state.
        */
                      ref oMissing, // Visible
                      ref oFalse,  // OpenAndRepair (false=no dialog)
                      ref oMissing, // DocumentDirection
                      ref oTrue,   // NoEncodingDialog
                      ref oMissing); // XMLTransform
    
    }
    catch (COMException x)
    {
      /*
       * BIG FAT HAIRY KLUDGE
       * If the document contains macros that cannot be located,
       * an exception 0x800A175D will be raised by call to Open.
       */
      if ((uint)x.ErrorCode == 0x800A175D && 0 != word.Documents.Count)
      {
        /*
         * A document has in fact been opened. Now all that's left 
         * is to convince Word to give me a reference to the damn
         * thing.
         */
        // document = word.ActiveDocument; // COM Exception
    
        //object oZero = 0;
        //document = word.Documents.get_Item(ref oZero); // Invalid index
    
        //object oOne = 1;
        //document = word.Documents.get_Item(ref oOne); // Invalid index
    
        //foreach (Document d in word.Documents) // Nothing in collection
        //{
        //  document = d;
        //  break;
        //}
      }
    
      if (null == document)
        throw; // murphy was an optimist
    }
    
    if (null == document)
      throw new Exception("No document after successful open.");
    }
    

    This signature unintentionally left blank.
    Monday, April 25, 2011 8:28 PM
  • Hi Nick,

    Could there be a field in the document that is referencing a macro that does not exist?

    In Word > Options >Advanced you can set fields to display as shaded and to display the field coding in all fields. You might find there's one that looking for a global macro.


    Regards, Rich
    Tuesday, April 26, 2011 12:13 AM
  • > throw; // murphy was an optimist

    Yes. I suppose I would aim for the "cut my losses" approach of logging the file name, quitting Word and restarting, but it wouldn't surprise me to learn that you can't get Word to Quit after "opening" one of these rogue documents. Without actually going through the process myself, I'm not sure what other stuff I might try, just to see if Word does something useful - perhaps

     a. verify that word.Documents.Count is actually 1, rather than some other non-0 value such as a Null or some such

    b. open a "known good" document as well and see what happens to the Count and whether that then allows me to reference the other document

    c. see if there is a way to automate Word using safe mode (I haven't looked) to try to open the document and inspect it without encountering this problem.



    Peter Jamieson
    Tuesday, April 26, 2011 7:20 AM
  • I checked for fields using macros and found none.  Not that it matters much as my goal is to try and handle the error via automation.

    A)  Document count is exactly 1 confirmed by the debugger.  Visually I've confirmed that the blank document you get when you launch word isn't crated.  So Documents.Count starts at 0 and changes to 1 during the Open. 

    B) For known good documents:
    word.ActiveDocument returns same document instance returned by Open
    word.Documents.get_Item(1) returns same document as above. 0 really is invalid.
    If I enumerate the collection, the first (and only) item is my document.

    So in normal circumstances any of my commented out methods would get me the document reference, though none of them work after the exception is raised.

    In contrast, while my applicaiton is stopped at a breakpoint I can alt-tab to word and manually walk through any of the operations that I intend to do via automation  Print / Save as PDF etc.  So, Word is ok with the document it just opened, and only the automation layer is borked. Though, since you mention it all add that "word.Quit" still works perfectly.

    C) Safe mode is an idea I haven't tried. 
       


    This signature unintentionally left blank.
    Tuesday, April 26, 2011 11:39 AM
  • Hi Nick,

    Just confirming that you have looked at ThisDocument class of the document for any VBA in the Document_New, Document_Open, AutoExec, AutoOpen, AutoNew events.

    Have you tried copying everything, execept the last paragraph mark, and pasting it into a new document and then testing the new document for this same behavior?

    Have you  tried through automation just opening an instance of Word and then executing the Document Open? If this automated method works, then it might be pointing you to a timing issue and Word, for some unknown reason, is not ready to deal with your Open command references.


    Regards, Rich
    Tuesday, April 26, 2011 1:25 PM
  • There doesn't appear to be anything at all under ThisDocument.

    Copying all but last paragraph to new document and testing new document does remove an error.  (I'm not sure what that proves, can you explain?)

    The sample code above does just that... Launch Word, Open Document.  It is the Open that's raising the identified COM exception even though I can visually confirm the document has been opened in the Word application. 

    At this point any attempts I've made so far to retrieve a reference to the open document from automation have failed.  To summarize everything I've tried so far:

    • doc is not returned from call to word.Documents.Open due to exception.
    • doc is not available via word.ActiveDocument due to same exception.
    • word.Documents.Count = 1 howerver foreach doesn't iterate any items from the collection.
    • doc is not available via word.Documents.get_Item(1) due to 'invalid index'.
    • word.Documents.Add() raises the collection count to 2.  However, get_Item(1) returns the blank document, get_Item(2) fails with invalid index--as does get_Item(0).
    • doc is not available as word.ActiveWindow.Document due to exception "word encountered an error"

    I also tried reconnecting to the automation layer after the document is open.

    • Marshal.BindToMoniker(fileName) returns an instance of a DocumentClass but any attempt to use the object results in an invalid cast exception.  "Cannot cast Word.DocumentClass to Word._Document"
    • Marhsal.GetActiveObject("word.Application") returns an instance to the running copy of word but that instance behaves like (and is in fact equal to) the one I already have.

     


    This signature unintentionally left blank.
    Tuesday, April 26, 2011 3:05 PM
  • BTW thanks everyone for the help so far.  If nothing else it's made me think it through enough that I can tell my customer I tried 'everything'
    This signature unintentionally left blank.
    Tuesday, April 26, 2011 3:11 PM
  • Hi Nick,

     

    I'm "C" challenged  J ... I write in VB so I don't fully recognize the syntax or process flow of C based logic.

     

    Why I was asking about the ThisDocument class and starting an instance of Word separately from any Open Document command was to try and simulate via automation what you found worked manually when you opened the document.  I was trying to determine if there was a timing problem or some latent code in the document itself that was causing the issue.

     

    Since “Doing a Maggie” on the document worked, it proves to me that what you have is a corrupted document.  It was probably corrupted by some add-in that your client used or is using, possibly even an artifact from a virus cleansing.

     

    Why the document opens manually and not by your application is probably due to an exception severity level that Word ignores but your app does not. That’s just a guess.

     

    The “Maggie”, a technique fist publicized by Margret Secara is a way to de-corrupt a document. Word stores hidden information about the document in/behind the last paragraph mark.  By copying everything, except that last paragraph mark, and pasting it into a new, fresh, un-corrupted document … many times you can salvage the damaged document.

     


    Regards, Rich
    Tuesday, April 26, 2011 4:28 PM
  • Hi Nick

    <<So in normal circumstances any of my commented out methods would get me the document reference, though none of them work after the exception is raised.

    In contrast, while my applicaiton is stopped at a breakpoint I can alt-tab to word and manually walk through any of the operations that I intend to do via automation  Print / Save as PDF etc.  So, Word is ok with the document it just opened, and only the automation layer is borked. Though, since you mention it all add that "word.Quit" still works perfectly>>

    You'll probably need to follow your thought about quitting Word if this happens and informing the user that a damaged document was encountered, with the error message. And possibly a help file about "doing a Maggie".

    FWIW, though, when this error crops up in the UI (and it does) there's a message box. And I wonder if the code is waiting for an answer to the message in the UI - but apparently the message never gets shown. So that's why your code is in a "can't see it" state.

    The other thought the occurs to me is that the "Interop" basically works through the same interfaces as VBA. If "macro storage" isn't available, then the interop interface into the document may well be blocked? I've never seen a document blocked, and the application still available, but as one Word MVP said, years ago: "Word rarely misses an opportunity to perplex"


    Cindy Meister, VSTO/Word MVP
    Tuesday, April 26, 2011 4:55 PM
    Moderator
  • <<

    Since “Doing a Maggie” on the document worked, it proves to me that what you have is a corrupted document.  It was probably corrupted by some add-in that your client used or is using, possibly even an artifact from a virus cleansing.

    >>
    I wouldn't be so sure in this case. A problem in a macro wouldn't be detected by a "Maggie" because in that case you're only copying the document stream. 
    The question is really what to do about .doc and perhaps other fiels that cause automation problems, and of course "what to do" depends at least partly on what the process is trying to achieve - if it just needs the document text, it might for example be feasible to strip off all macro code by modifying the .doc Structured Storage files directly (outside Word) or manipulating the .docx files, etc. prior to processing via the Word object. If the process is trying to modify files in bulk, that's probably not an option.

    Peter Jamieson
    Tuesday, April 26, 2011 4:56 PM
  • Hi Nick

    In my experience, this error almost always means that there's a broken reference in a template attached to an open document, or in an add-in (that is, a template loaded as a "global template" aka add-in). I seem to remember that back in Word 2003 days I could repro it on demand.

    The error may not come from the document in which your code is running, or the document your code is manipulating, or the template to which that document is attached. It can be any loaded template or add-in.

    If that's the case, then you just have to trap the error and tell the user that life isn't going to continue today.

    FWIW, I put a trap for this error in all my standard error handlers for just this reason. The user could have anything on their machine. But if something on the machine is broken, my code will look like it's causing the problem.

    To identify the culprit, one by one look at the templates attached to all open documents, and look at each loaded add-in (ie global template loaded as an add-in) to find the broken reference.

    Cheers

    Shauna

    Shauna Kelly
    http://www.shaunakelly.com/word

    <Nick F. _> wrote in message news:7b4dc7a6-804b-4d88-9dae-e46dcc05bffb@communitybridge.codeplex.com...

    BTW thanks everyone for the help so far. If nothing else it's made me think it through enough that I can tell my customer I tried 'everything'


    This signature unintentionally left blank.

    Tuesday, April 26, 2011 6:08 PM
  • Wow tons of replies.  Thanks again all.

    I do not doubt the broken reference.  When I launch the document from windows explorer I see the add-in tab and the two toolbar buttons that if clicked say the equivalent of "can't find this thingy" ;-)   Really my angst comes from the fact that after the exception the automation layer is completely borked beyond any chance of repair...while Word itself has the document open and will muddle through and do just about anything I can ask of it ...short of actually executing the missing macro(s).  Templates on my machine(s) are fine (can't speak for customers at this point) they simply don't have what word is looking for.

    As for my process, all *I* need to do with the document is:
      Launch Word | Open Document | Print to "that printer" | Close Document | Exit Word
    or 
      Launch Word | Open Document | Export to PDF | Close Document | Exit Word

    Not exactly rocket science.

    However I think at this point I (who'm I kidding... *We*) have ruled out anything I can do without user intervention.  The actual production code runs as a service (yes I know the official disclaimer by chapter and verse) so that's not very helpful.  I've already informed my customer that there's not much I can do in this case except flag it with a code and message they can identify and move to the next document in line.


    This signature unintentionally left blank.
    Tuesday, April 26, 2011 8:51 PM
  • Hi Nick,

    Just one more thought ... does that document have any unresolved Tracked Changes?


    Regards, Rich
    Tuesday, April 26, 2011 8:56 PM
  • <<

    As for my process, all *I* need to do with the document is:
      Launch Word | Open Document | Print to "that printer" | Close Document | Exit Word 
    or 
      Launch Word | Open Document | Export to PDF | Close Document | Exit Word

    >>
    In that case, if necessary, for those documents that fail to open, you might be able to
     a. start Word with a blank document
     b. use Insertfile to insert the document
    In that case,
     c. the document does not bring its macros with it. Whether the macros can still cause a problem, I don't know
     d. unfortunately I don't think you could guarantee that the document would have identical appearance (there might be problems with section layout, headers/footers, and so on) 

    Peter Jamieson
    Tuesday, April 26, 2011 9:15 PM
  • No tracked changes that I can see.

    I tried InsertFile (a worthy idea, btw) and it did load the document and I could continue processing.  Unfortunately as you predicted, formatting data was lost.  Accuracy is important.

    Thanks


    This signature unintentionally left blank.
    Wednesday, April 27, 2011 12:00 PM
  • Check if the General tab on the templates file properties shows "Security: This file came from another computer and might be blocked to help protect this computer" and has an "Unblock" button. We have had the same symptoms solved by unblocking the template. You can also programmatically remove the Zone.Identifier alternate data stream.

    Tuesday, May 3, 2011 5:06 PM
  • Greg,

    Not sure exactly what you mean.  Yes, my sample1.doc file came from another computer.  So what template are you talking about?  The one on my customer's machine 3000 miles away, or the one in my test machine which (to the best of my knowledge) is unchanged from the day the Office install put it there.

    I'll have to look into the zone identifer idea, though having tried everything else... i'm more than usually pessimistic.

     


    This signature unintentionally left blank.
    Wednesday, May 4, 2011 4:06 PM
  • Sorry, I meant the document file. We were having the problem trying to open certain templates for editing.
    Thursday, May 5, 2011 7:37 PM