Article by - Sheela E.N, Sonata Software Limited
Macro-enabled files (.docm) have the same file format as macro-free files (.docx), but contain additional parts that macro-free files do not. The Open XML format stores the various components of the document, the charts, graphics, macros, and other elements, separately in parts. Developers can programmatically determine if any macro-enabled code exists in a WordprocessingML document by inspecting the package file and can remove those parts, so that the code can cause no harm.
This article explains the process of extracting and removing macro enabled part from a document using Open XML SDK in C# project.
1. Create a C# project; add a reference to openxml dll
a. In the Add Reference dialog box, click the .NET tab.
b. Scroll to the Microsoft.Office.DocumentFormat.OpenXml option, select it, and then click OK.
2. Import the namespace to refer to the dll
using Microsoft.Office.DocumentFormat.OpenXml.Packaging;
3. Declare a string variable which stores relationship namespace for vbaProject
const string relTypeVBA = "http://schemas.microsoft.com/office/2006/relationships/vbaProject";
4. Open the document to get the main document part.
WordprocessingDocument wordDoc = WordprocessingDocument.Open(filename, true);
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
5. Iterate each part in the main document to get macro part
foreach (IdPartPair var in mainPart.Parts)
{
if (var.OpenXmlPart.RelationshipType.ToString() == relTypeVBA)
OpenXmlPart macroPart = (OpenXmlPart)var.OpenXmlPart;
mainPart.DeletePart(macroPart);
break;
}
6. Since the document is macro enabled, its content type is set to - "application/vnd.ms-word.document.macroEnabled.main+xml"
7. After removing macro part from the main document, have a copy of the content of main document and remove the same.
XmlDocument mainpartdoc = new XmlDocument();
mainpartdoc.Load(mainPart.GetStream());
wordDoc.DeletePart(mainPart);
8. Create a main document and get the content of the part saved in step no 7
MainDocumentPart main = wordDoc.AddMainDocumentPart();
StreamWriter mainstream = new StreamWriter(main.GetStream(FileMode.Create, FileAccess.Write));
mainpartdoc.Save(mainstream);
9. Change the content type of the main document from macro enabled to macro free and close the handler
wordDoc.ChangeDocumentType(WordprocessingDocumentType.Document);
wordDoc.Close();
10. Move the file to another location with .docx extension.(You can change the logic of this to suite your requirement)
string newfilename = @"c:\MacroFree.docx";
File.Move(filename, newfilename);