Here is the code that will work for most types, but only in a Windows window, as this requires OLE technology. In fact, it ultimately depends on how your computer is configured due to the proximity of OLE, so you need to try this a bit.
This is an example of the code that creates the .docx file:
// make sure this all is running in an STA thread (for example, mark Main with the STAThread attribute) // the file you want to embed string embeddedDocumentPath = @"C:\mypath\myfile.txt"; // a temp file that will be created, and embedded in the final .docx string packagePath = @"C:\Temp\test.bin"; // a temp image file that will be created and embedded in the final .docx string packageIconPath = @"C:\Temp\test.emf"; // package embeddedDocumentPath -> create the two OpenXML embeddings Packager.PackageFile(packagePath, packageIconPath, embeddedDocumentPath); // create the word doc using (var doc = WordprocessingDocument.Create(@"C:\mypath\ContainingDocument.docx", WordprocessingDocumentType.Document)) { var main = doc.AddMainDocumentPart(); // add icon embedding var imagePart = main.AddImagePart(ImagePartType.Emf); imagePart.FeedData(File.OpenRead(packageIconPath)); // add package embedding var objectPart = main.AddEmbeddedObjectPart("application/vnd.openxmlformats-officedocument.oleObject"); objectPart.FeedData(File.OpenRead(packagePath)); // build a sample doc main.Document = BuildDocument(main.GetIdOfPart(imagePart), main.GetIdOfPart(objectPart), "Package"); } private static Document BuildDocument(string imagePartId, string objPartId, string progId) { var shapeId = "R" + Guid.NewGuid().ToString("N"); // come up with a unique name... var element = new Document( new Body( new Paragraph(new Run(new Text("This is the containing document."))), new Paragraph(new Run(new Text("This is the embedded document: "))), new Paragraph( new Run( new EmbeddedObject( new v.Shape( new v.ImageData { RelationshipId = imagePartId, // rel to image part Title = "" // this is important! }) { Id = shapeId }, new ovml.OleObject { Type = ovml.OleValues.Embed, DrawAspect = ovml.OleDrawAspectValues.Icon, ProgId = progId, // COM progid Id = objPartId, // rel to embedded part ShapeId = shapeId, // link to shape ObjectId = "R" + Guid.NewGuid().ToString("N") // come up with a unique name... } ))) ) ); return element; }
And here is the utility code that will create the package and image file (EMF) from the input file. Now for PDF this code may fail (for example, I said that it depends on whether Adobe Reader is installed or not, its version, etc.). If it does not work in OleCreateFromFile, you can try to create / add a registry key named "PackageOnFileDrop" as follows:
HKEY_CLASSES_ROOT\AcroExch.Document.DC\PackageOnFileDrop
I am not sure why the PDF files do not support OleCreateFromFile directly (undercovers, if you installed Acrobat Reader, this is all processed by AcroRd32.exe, which is the Adobe COM server provider), I think it can be a security feature, and I donβt know how Word gets around this ...
public static class Packager { public static void PackageFile(string outputFile, string outputImageFile, string inputFile) { if (outputFile == null) throw new ArgumentNullException(nameof(outputFile)); if (outputImageFile == null) throw new ArgumentNullException(nameof(outputImageFile)); if (inputFile == null) throw new ArgumentNullException(nameof(inputFile)); IStorage storage; CheckHr(StgCreateStorageEx( outputFile, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, STGFMT_DOCFILE, 0, IntPtr.Zero, IntPtr.Zero, typeof(IStorage).GUID, out storage));