2
votes

I'm trying to make word document readonly using open xml manipulations. I'm not sure if I'm on the right track or completely wrong track entirely. I've included all my relevant code way below. It doesn't seem to have the intended (or any) effect.

I have opened the xml and verified that some permissions things are happening in the xml, although I'm not sure if its the right things.

This is one of the things that happens to the xml file in the docprop/app.xml file

<?xml version="1.0" encoding="UTF-8"?>
<ap:Properties xmlns:ap="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
   <ap:DocSecurity>4</ap:DocSecurity>
</ap:Properties>

This is one of the things that happens in the word/settings.xml file

<?xml version="1.0" encoding="UTF-8"?>
<w:settings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
  <w:documentProtection w:enforcement="true" w:edit="readOnly"/>
</w:settings>

my code used to add readonly permissions to a documents is below

public static class OpenXMLManipulations
{

    public static void AddReadonlyPermissions(string filePath)
    {
        using (var myDocument = WordprocessingDocument.Open(filePath, true))
        {


            if (Equals(myDocument.ExtendedFilePropertiesPart, null))
                myDocument.AddExtendedFilePropertiesPart();

            if (Equals(myDocument.ExtendedFilePropertiesPart.Properties, null))
                myDocument.ExtendedFilePropertiesPart.Properties = new Properties();

            myDocument.ExtendedFilePropertiesPart.Properties.DocumentSecurity
                = new DocumentSecurity("4");

            myDocument.ExtendedFilePropertiesPart.Properties.Save();

            /*
             * Code 4 enforces read only 
             * http://msdn.microsoft.com/en-us/library/documentformat.openxml.extendedproperties.documentsecurity(v=office.14).aspx
            */


            if (Equals(myDocument.MainDocumentPart.DocumentSettingsPart, null))
                myDocument.MainDocumentPart.AddNewPart<DocumentSettingsPart>();

            if (!Equals(myDocument.MainDocumentPart.DocumentSettingsPart.Settings, null) &&
                (myDocument.MainDocumentPart.DocumentSettingsPart.Settings.ChildElements.Count > 0))
            {

                var dps = myDocument.MainDocumentPart.DocumentSettingsPart
                     .Settings.ChildElements.OfType<DocumentProtection>();

                foreach(var _dp in dps)
                    _dp.Remove();

            }

            var dp = new DocumentProtection();
            dp.Edit = DocumentProtectionValues.ReadOnly;
            dp.Enforcement = OnOffValue.FromBoolean(true);

            if (Equals(myDocument.MainDocumentPart.DocumentSettingsPart.Settings, null))
                myDocument.MainDocumentPart.DocumentSettingsPart.Settings = new Settings();


            myDocument.MainDocumentPart.DocumentSettingsPart.Settings.AppendChild(dp);


            myDocument.MainDocumentPart.DocumentSettingsPart.Settings.Save();

            //myDocument.Close();
        }

    }
}

I'm a bit miffed with this process. Any pointers to what I'm doing wrong?

When I open the sample word document, there is no indication that I've added any permsissions modifiers, ie. everything opens normally.

Thanks, Sam

1

1 Answers

0
votes

Have you tried changing the output file extension to .zip and having a look at the output XML in the package?

The change to the app.xml isn't strictly necessary for the OpenXML standard; and the edit and enforcement attributes of the w:documentProtection element will make the document read-only. However, the user will be able to re-enable editing without supplying a password.

If you want to make the document read-only and force a password to be supplied to enable making it editable there is the Document Protection element of the Document Settings part that enables this (17.15.1.29), then read-only can be enforced.