none
DocumentSettingsPart.Settings = new Settings() corrupts /word/_rels/document.xml.rels!? this is why? RRS feed

  • Question

  •  MainDocumentPart temporaryMainDocumentPart = ((WordprocessingDocument)this.defaultOoxmlPackage).MainDocumentPart;                   
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
                if (temporaryMainDocumentPart.DocumentSettingsPart == null) temporaryMainDocumentPart.AddNewPart<DocumentSettingsPart>(); 
    
    
    
    
    
    
    
                if (temporaryMainDocumentPart.DocumentSettingsPart.Settings == null) temporaryMainDocumentPart.DocumentSettingsPart.Settings = new Settings();
    
    
    
    
    
    
    
                temporaryMainDocumentPart.DocumentSettingsPart.Settings.Save();
    
    
    
    
    
    
    
    

    Above are my codes: when skip the " temporaryMainDocumentPart.DocumentSettingsPart.Settings = new Settings();" line, the  "/word/_rels/document.xml.rels" file can be extracted by WinRar correctly(word can open the whole package as well ), however when the line is inserted, the WinRar reports that the "/word/_rels/document.xml.rels" file as "CRC Error" ,Word reports unknown error and prompt for repair against the docx file.

    _ My Blog: xiaoyuvax.spaces.live.com Follow me on Twitter: twitter.com/xiaoyuvax
    Thursday, November 12, 2009 4:12 AM

All replies

  • Thanks for the question.

    I need more information to figure out the issue, is the package a new created package or an existed one? which CTP are you using?
    Friday, November 13, 2009 6:44 AM
    Moderator
  • SDK version:August 2009 CTP

    My Scenario:
    I am creating a new docx file, after package created and the maindocument added,ad with a CoreFilePropertiesPart added and filled with something there before, i'd like then to attach a customXml Schema to the documentSettings, so i have to make the DocumentSettingsPart available which is defaulty "null", however when this line :"temporaryMainDocumentPart.DocumentSettingsPart.Settings = new Settings();" is there, the program seems running well and delivers a result docx file as normally, but the result docx is a corrupted one which can not be opened by word whereby gives no detailed reason and prompts for repair. I use winrar to open the package, and found the /word/_rels/document.xml.rels can not be extracted,and it says CRC error.  However, when i removed that line,my program delivers a "good" docx,and i checked the docx file with both word and winrar and everything is normal.

    don't know why...
    after hundreds of test of all cases , i am totally frustrated... 
    and i am wondering if the CoreFilePropertiesPart may cause such problem... cos i've reported in former post that the RootElement property of CoreFilePropertiesPart class is not functioning normally (it's kind of similar to this Settings property,they are both OpenXmlRootElement-s, might there be something wrong or bugs in the shared saving code or common procedures in the SDK called by these OpenXmlRootElements?)...  (http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/eddd3475-ec53-4288-ad1e-598593e1b368), i will test this later...

    but there's no detail information for debugging, that gets me headache,when i re-open the ill docx file, my program reports(or just say the SDK reports) the part's compression length is inconsistent or so.



    Welcome to My Blog: xiaoyuvax.spaces.live.com | Follow me on Twitter: twitter.com/xiaoyuvax
    Friday, November 13, 2009 4:10 PM
  • Thanks for provide these info,  its really weird, from your description, I trying the following code:

      WordprocessingDocument doc = WordprocessingDocument.Create(@"d:\ucm\setting1.docx", WordprocessingDocumentType.Document);
                MainDocumentPart temporaryMainDocumentPart=doc.AddMainDocumentPart();
                doc.AddCoreFilePropertiesPart();
                               
               
                if (temporaryMainDocumentPart.DocumentSettingsPart == null) temporaryMainDocumentPart.AddNewPart<DocumentSettingsPart>();
               
                if (temporaryMainDocumentPart.DocumentSettingsPart.Settings == null) temporaryMainDocumentPart.DocumentSettingsPart.Settings = new Settings();
                            temporaryMainDocumentPart.DocumentSettingsPart.Settings.Save();
                            doc.Close();



    and the /word/_rels/document.xml.rels is there which can be extracted, so I guess maybe this is some thing happen when you filled data to CoreFilePropertiesPart , could you share with me that part of data, so I can do more investigation.

    BTW, 
    Have you tried to open that corrupt document by sdk, what kind of error it reported?

    Thursday, November 19, 2009 11:55 AM
  • I tested this again just now with Autosave enabled(it was disabled in my earlier trials)... it still can not work...

    When i open the file with SDK,it just says "inconsistent compression length" i guess it means that it can not verify the CRC,cos the /word/_rels/document.xml.rels is corrupoted with a failing CRC verification

    And i found that DocProps/Core.xml does not exist in the package this time, instead there is a "Package" folder in the ZIP file... and i found \Package\Services\Metadata\core-properties\d0eebee1495e4dca96b85cee3f248514.psmdcp where my core properties were stored right there. i guess this is due to that i've given up adding a CoreFileProperties part, cos i found out lately that i could still store my core properties through OpenXmlPackage.PackageProperties instead(when open a docx the PackageProperties is not null, however when create a docx,it is null and adding CoreFileProperties Part is necessary). Even though, the "corruption" problem is still there.

    For the data fed to the CoreFileProperties part in my earlier trials, it is only a standard Core.xml contents extracted from an empty docx file... which does work normally when creating an empty docx.Anyway, now since i bypassed this data feeding step(through openning existing docx rather than creating a new),the problem still exists,therefore i believe the problem does not lie in the feeding...

    i guess there must be certain writting action that corrupts the .rel file(possibly during persist the relationship data),which is not controlled by my code but certain process within the SDK low-level...

    and i think i should test such scenario in another new project, to get the code isolated from my current project's environment, and to get the processes model simplified bit by bit as to know which section is wrong...

    but that there is too little and un-detailed debugging information provided by SDK is a real headache..

    Welcome to My Blog: xiaoyuvax.spaces.live.com | Follow me on Twitter: twitter.com/xiaoyuvax
    Friday, November 20, 2009 5:50 PM
  • The document must be closed with a call to wordprocessingDocument.Close() or with the using(...) pattern. Can you please check whether your have called the Close() function in your code?

                using (var document = WordprocessingDocument.Open(testfile, true, new OpenSettings() { AutoSave = true }))

                {

                    var documentRoot = doc.MainDocumentPart.Document;

                    var p = documentRoot.Body.GetFirstChild<Paragraph>();

                    // modify the content
                    ......

                }



    The name of the core properties part is givern by the underlaying System.IO.Packaging api (which the SDK is based on) when you set the core properties through OpenXmlPackage.PackageProperties. And yes, the name is not so friendly.
    Monday, November 30, 2009 10:47 AM
  • of course i've called .Close() and before calling which,document.Save() and Package.Flush() were also called as well ensures the data was properly fed to stream. i am so sure about this...





    Welcome to My Blog: xiaoyuvax.spaces.live.com | Follow me on Twitter: twitter.com/xiaoyuvax
    Monday, November 30, 2009 1:39 PM
  • I've finally located how the problem occurs, that is:

    it seems that Package.Flush() doesn't really save everything necessary to disk, but you must call Close() rather than Flush() to get everything(including  CRC values for subordinary relationships at least i guess) really FLUSHED into a ZIP packaging. see an example

    //_______________________________
    Stream f1 =null;
    Stream f2 =null;
    Stream fs = new FileStream(...);
    Package newPackage = Package.Open(fs,...);

    (... certain operation to the package contents...)

    newPakcage.Flush();

    CopyStream(fs, fs1);

    newPackage.Close();

    CopyStream(fs, fs2);
    //_______________________________

     and you'll see that fs1 doesn't equal to fs2... this is why my code always produces bad package with .rel file corrupted, cos my code persists(in case of SaveAs...) the stream to disk before newPackage.Close() is called.  When i rearranged the order of these lines, the problem gets solved.

    hope this helps others...

    Welcome to My Blog: xiaoyuvax.spaces.live.com | Follow me on Twitter: twitter.com/xiaoyuvax
    Thursday, December 3, 2009 7:00 AM
  • The document must be closed with a call to wordprocessingDocument.Close() or with the using(...) pattern. Can you please check whether your have called the Close() function in your code?

    using (var document = WordprocessingDocument.Open(testfile, true, new OpenSettings() { AutoSave = true }))

    {

    var documentRoot = doc.MainDocumentPart.Document;

    var p = documentRoot.Body.GetFirstChild<Paragraph>();

    // modify the content
    ......

    }



    The name of the core properties part is givern by the underlaying System.IO.Packaging api (which the SDK is based on) when you set the core properties through OpenXmlPackage.PackageProperties. And yes, the name is not so friendly.

    It's very detailed, Thanks for your explanation!
    Saturday, January 22, 2011 5:13 AM