如何在没有互操作程序集的情况下将任何文件类型嵌入到Microsoft Word中

我正在尝试这样做如何使用OpenXml 2.0将任何文件类型嵌入到Microsoft Word中

但只使用OpenXml SDK 2.5(没有互操作程序集)

我可以使用以下代码示例嵌入其他单词(或办公室)文件
(我们需要从NuGet和WindowsBase添加对DocumentFormat.OpenXml的引用)

但我无法重构它以接受任何文件类型(pdf,mp3等)

using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using DocumentFormat.OpenXml; using v = DocumentFormat.OpenXml.Vml; using ovml = DocumentFormat.OpenXml.Vml.Office; using System.IO; class Program { static void Main(string[] args) { //Just update the following 2 variables to point to existng files string containingDocumentPath = @"C:\Temp\Word\ContainingDocument.docx"; string embeddedDocumentPath = @"C:\Temp\Word\EmbeddedDocument.docx"; CreatePackage(containingDocumentPath, embeddedDocumentPath); } private static void CreatePackage(string containingDocumentPath, string embeddedDocumentPath) { using (WordprocessingDocument package = WordprocessingDocument.Create(containingDocumentPath, WordprocessingDocumentType.Document)) { AddParts(package, embeddedDocumentPath); } } private static void AddParts(WordprocessingDocument parent, string embeddedDocumentPath) { var mainDocumentPart = parent.AddMainDocumentPart(); GenerateMainDocumentPart().Save(mainDocumentPart); var embeddedPackagePart = mainDocumentPart.AddNewPart("application/vnd.openxmlformats-" + "officedocument.wordprocessingml.document", "rId1"); GenerateEmbeddedPackagePart(embeddedPackagePart, embeddedDocumentPath); var imagePart = mainDocumentPart.AddNewPart("image/x-emf", "rId2"); GenerateImagePart(imagePart); } private static Document GenerateMainDocumentPart() { 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() { Title = "", RelationshipId = "rId2" } ) { Id = "_x0000_i1025", Style = "width:76.5pt;height:49.5pt", Ole = TrueFalseBlankValue.FromBoolean(false)//v.BooleanEntryWithBlankValues.Empty }, new ovml.OleObject() { Type = ovml.OleValues.Embed, ProgId = "Word.Document.12", ShapeId = "_x0000_i1025", DrawAspect = ovml.OleDrawAspectValues.Icon, ObjectId = "_1299573545", Id = "rId1" } ) //{ // DxaOriginal = (UInt32Value)1531UL, // DyaOriginal = (UInt32Value)991UL //} ) ) ) ); return element; } public static void GenerateEmbeddedPackagePart(OpenXmlPart part, string embeddedDocumentPath) { byte[] embeddedDocumentBytes; // The following code will generate an exception if an invalid // filename is passed. using (FileStream fsEmbeddedDocument = File.OpenRead(embeddedDocumentPath)) { embeddedDocumentBytes = new byte[fsEmbeddedDocument.Length]; fsEmbeddedDocument.Read(embeddedDocumentBytes, 0, embeddedDocumentBytes.Length); } using (BinaryWriter writer = new BinaryWriter(part.GetStream())) { writer.Write(embeddedDocumentBytes); writer.Flush(); } } public static void GenerateImagePart(OpenXmlPart part) { #region Icon Bytes // Best practice is that this icon should be stored as a resource // in the assembly instead of as a Base64 string. string iconBytes = @" AQAAAGwAAAAAAAAAAQAAAGQAAAAuAAAAAAAAAAAAAAAODgAAGAkAACBFTUYAAAEAbBQ AABAAAAACAAAAAAAAAAAAAAAAAAAAQAYAALAEAAA0AgAApwEAAAAAAAAAAAAAAAAAAN ycCACldQYAGAAAAAwAAAAAAAAAGQAAAAwAAAD///8AcgAAAKAQAAAjAAAAAQAAAEIAA AAgAAAAIwAAAAEAAAAgAAAAIAAAAACA/wEAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8A AAAAAAAAAP///wAAAAAAbAAAADQAAACgAAAAABAAACAAAAAgAAAAKAAAACAAAAAgAAA AAQAgAAMAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAA/wAA/wAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuaSV/5F8av9 4YUz/alM8/2ZON/9iSjL/YEgw/2BIMP9gSDD/YEgw/2BIMP9gSDD/YEgw/2BIMP9gSD D/YEgw/2BIMP9gSDD/YEgw/2BIMP9gSDD/YEgw/2BIMP9gSDD/YEgw/wAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAC6pZb//Orf/9/NxP/dxbf/3r2s/964ov/jspj/5bOQ /+WzkP/ls5D/5bKO/+awi//nr4j/6a2F/+qsgv/rqn//7Kd7/+6ld//vo3P/8aFv//G ga//znmj/851l//SbY/9gSDD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALqllv /86+H//Ovh//zr4f/86+D/++rf//vp3//76d7/++nd//ro3P/759z/+uba//rm2f/65 df/+uTW//rj1P/64tP/+eDS//ngz//53s7/+d3M//ncyv/528j/9Jxl/2BIMP8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu6aX//zu5P/77eT//O3k//vs5P/77OP//Ov i//vr4v/76+D/++rf//vp3//76d3/++jc//rn2v/65tr/+uTY//rk1v/54tT/+uHT// rg0f/538//+d7N//ncyv/znWf/YEgw/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AC7p5j//O/n//zv5//77+b//O/m//zv5v/87eX//O3k//zt5P/87OP//Ovi//zq4f/8 6t//++re//vo3P/759v/+uba//rl1//65NX/+uLT//nh0f/64ND/+t/O//Keav9gSDD /AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALyomP/88er//PHp//zx6v/88On//P Dp//zw6P/97+j//O/n//zu5v/87uX//O3k//zs4//87OH/06mL/9Koif/Rpof/0aWG/ 9CkhP/Po4P/+uPV//rh0v/64ND/8aBt/2BIMP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAvama//3z7f/98+3//fPs//3y7P/98+v//fLr//zy6v/98er//fHp//zw6P/ 87+f//O7m//zt5P/87eP//Ovh//vq3//76d3/++jc//rm2f/65Nf/+uPW//ri0//won D/YEgw/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC+qpv//fXv//307//jwaj/4 r+l/+G9o//fu6H/3rme/923nP/btZr/2rOX/9mxlf/YsJP/166R/9asj//Vq43/1KmL /9Koif/Spoj/0aWG//vn2v/65dj/+uPW/++jc/9gSDD/AAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAL+rnP/+9vH//fbx//328f/99vH//fbx//718P/99fD//fXw//307/ /98+7//fPt//3y7P/88er//PDp//zv5//87uX//O3k//zr4v/86t//++jd//vn2v/65 dj/7aV3/2BIMP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwKye//348//99/P/ 5sWt/+XDq//jwaj/4b6l/+C8ov/euqD/3rmf/923nP/ctpr/2rSY/9mylv/YsJP/166 R/9atj//Vq43/1KqL/9Ooiv/76uD/++nd//vn2//tp3v/YEgw/wAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAADBrp7//vn1//759f/++fX//vj1//749f/++PX//vj1//339 P/+9/P//vfz//338v/99vH//fXw//307v/98+3//PLr//zx6f/87+f//O7k//vs4v/7 6uD/++jd/+upf/9gSDD/AAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAMKun//++vf //vr3/+jJsf/nx6//5sWt/+XDq//jwqj/4sCm/+G+pP/gvKH/3rqf/924nP/ctpr/2r SY/9mylv/YsJT/166R/9atj//Vq47//O7l//zs4//76t//6auD/2BIMP8AAAAAAAAAA AAAAAAAAAABAAAABQAAAA0AAAAUrpyP/9/c2f/b2NX/1dHO/9DLyv/JxcP/xcG//8rG xP/Oysj/8ezp//v28//9+PX//vj1//749P/+9/P//fbx//318P/99O3//fLr//zx6f/ 87+f//O3k//zs4v/orof/YEgw/wAAAAAAAAAAAAAAAQAAAAMAAAAOAAAAIgAAADWQgX b/tLGv/62rqf+TfGv/mIN0/6KQgv+3p5n/yrus/8Ksmf+6oY//3bqh/+C9o//gvKL/3 rqf/924nf/ctpv/27SY/9mylv/YsJT/16+S//zx6f/97+f//O3k/+avi/9gSDD/AAAA AAAAAABuOSXAczwnzWw4JNF5VEbekHpw6q+dlv/FuLL/3tbS//Xx7P/8+PP/+/bv//n 06//48uf/vqmb/9jW1P/r6Ob//fr4//77+f/++vj//vn2//749f/99/P//fbx//307/ /98+3//fLr//3w6P/87ub/5bGP/2BIMP8AAAAAAAAAAIxLMPDeuar/vpqL/9Gmlf/// //////////////+/vz//vz6//369v/8+PP/+/bv//n06//Bqpz/v6OO/9KznP/jwaj/ 4sCn/+G+pP/gvKL/37qg/924nf/ctpv/27SY/9qzlv/98+3//PHq//zw6P/ls5L/YEg w/wAAAAAAAAAAjk0z8Nq2qf+xclj/0720///////68vD/6MS9///////z4t3/2Z6T// 369v/8+PP/+/bv/828sP/U0tL/6+no//78+//+/Pv//vz6//77+f/++vj//vn2//749 P/99/P//fbx//307v/98u3//fHq/+S1lv9gSDD/AAAAAAAAAACQUDbw2bWm/6RTMf+4 jXv///////nx7/+3XEX/9+3q//Hg3P+zVDv/7NTN//369v/8+PP/2MvB/9HPz//q6Oj //vz8///9/P/OoYH/zqGB/86hgf/OoYH/zqGB/86hgf/OoYH//vXw//307v/98uz/4r ea/2BIMP8AAAAAAAAAAJJSOfDYtKT/ok8s/6RoT////////v38/6RHJ/+/fWf/79/Z/ 6dNL/+5cln//Pj1//369v/j2NH/z87N/+no5//+/fz///38//PKqv/mvqL/58On/+e/ pP/is5P/5LaX/86hgf/+9vH//fTv//3z7f/huZz/YEgw/wAAAAAAAAAAlFU88Nizpf+ iTyz/kEUm////////////n0gk/8WQev/Il4P/oEon/9WwoP/Ooo///vz6//Dq5f/My8 v/6Ofn//79/f///v3/88qq/9mpiP/fspL/5bmb/+Cxkv/kt5n/zqGB//728v/99vD// fPu/+G6n/9gSDD/AAAAAAAAAACWWD/w2LSl/6RPLf+LORb/8evp//////+lVTP/6dbO /7FrTv+fSSb//v38/69nSf/v4dn/+/j2/8nIyP/m5eX//fz8///+/f/zyqr/6cGl/+j DqP/mvqL/3q+O/+O4mf/OoYH//vfz//328f/99e//37uh/2BIMP8AAAAAAAAAAJlbQf Dmy8H/x451/7F3X//h1c//+/j3/6ZXNv/VsKD/7+Hc/6ZXNv//////wYly/7yAZ//+/ vz/y8rK/+Xk5P/9/Pz///79//PKqv/049f/7NjK//v18P/kwqr/48Gn/+K/pf/eu6X/ 3rul/967pf/fvKP/YEgw/wAAAAAAAAAAm15E8OnQx//PmoX/vYZx/9bCuv/59PH/69j R/+zb1P/////////////////////////////////R0ND/5eTk//z7+////v3/88qq// 359v/+/f3/69fJ/76snf+MdmP/iHJe/4FrV/96Y07/cltF/2pTPP9gSDD/AAAAAAAAA ACVXEPk59DG/9eql//IlH//z7Oo//////////////////////////////////////// /////////+Df3//p6Oj//fz8///+/f/zyqr///////v07//049f/v62d/+zSv//qzrv /58q1/+TErv/hvqn/YEgw/yUkJCkAAAAAAAAAAG1EM6XVsKH/8N3W/9Sij//VsaL/// ////////////////////38/P/x6eX/8+zq//Tv7v/cysL/9PPz//v6+v/+/f3///7+/ /PKqv/zyqr/88qq//PKqv/Brp///+7k//vo3P/03tD/7tTD/2BIMP8lJCQpGBgXGgAA AAAAAAAAIBQPMKhrUfzkyL7/8uDa/9KllP/SpZT/0qWU/9Wol//XqZj/16mY/9iqmP/ SpZT/0qWU/7WEbv/8+/v//v39///+/v///v7///79//7+/f///fz///37/8KwoP//7u T/++jc//Xe0P9lTjb/JSQkKRgYFxoAAAAAAAAAAAAAAAAAAAAAQSkgYKZrUvbUrp//9 eXf//Tk3v/05N7/9OTe//Xl3//15d//9eXf//Xl3//15d//u4hz//79/f///v7///7+ ///+/v///v3///39///9/P///fv/xLKj///u5P/76Nz/bFU+/yUkJCkYGBcaAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAFg4LIXFJOKWcZU3kr3JX/69yV/+vclf/r3JX/69yV/ +vclf/r3JX/69yV/+9i3T///7+///+/v///v7///7+///+/v///v3///39///9/P/Gt KT//+7k/4NuWf8lJCQpGBgXGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAADRv7H//////////////////////////////////////////////////// ////+/v////7///7+///+/v///f3///38/8i1pf+chnT/JSQkKRgYFxoAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANG/sf/Rv7H/0b+x/9G/s f/QvrD/z72v/8+9r//PvK7/zbut/827rP/Nuaz/zLmr/8u4qv/Kt6n/yreo/8m2p//I tqf/ybam/yUkJCkXFxcZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAYAAAADAAAAAAAAAISAAAADAAAAAEAAABSAAAAcAEAAAEA AAD1////AAAAAAAAAAAAAAAAkAEAAAAAAAAAQAAiVABhAGgAbwBtAGEAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT310CQ AA3LMCWf//AADy4QAAAABkWczmMADASrNZAAAAAAAAAADwtAoAAAAAAEkaZlkAAAAAv EqzWQAAAADLdGRZAACJAXznMAAAbI8BfOcwAAAAAAAAAAAAAAAAAAAAiQFcf0daBAAA AGzmMAAXdGRZAgAAAAFKT33o5TAAAAAAADD6MAA0mDN3BZtGCv7///8QTjd3IU83dwA AZFkAAAAAdAkAAMzmMAAAAAAAwOYwAPW4LnbA5jAAB7kudgAAZFkAAAAAAABkWQAAAA Dc5jAA3OYwACDnMAAhZR9YBQAAANzmMAAAbI8BfOcwAAAAAAAkAAAA3LMCWSA3A1lkd gAIAAAAACUAAAAMAAAAAQAAAFQAAAC0AAAAAAAAACIAAABkAAAALgAAAAEAAAAAAA1C AAANQgAAAAAiAAAAEQAAAEwAAAAEAAAAAAAAAAAAAABmAAAAQgAAAHAAAABFAG0AYgB lAGQAZABlAGQAIABEAG8AYwB1AG0AZQBuAHQAAAAGAAAACAAAAAYAAAAGAAAABgAAAA YAAAAGAAAABgAAAAMAAAAHAAAABgAAAAUAAAAGAAAACAAAAAYAAAAGAAAABAAAACUAA AAMAAAADQAAgEYAAAAgAAAAEgAAAEkAYwBvAG4ATwBuAGwAeQAAAAAARgAAADAAAAAk AAAARQBtAGIAZQBkAGQAZQBkACAARABvAGMAdQBtAGUAbgB0AAAARgAAAGAAAABUAAA AQwA6AFwAUABSAE8ARwBSAEEAfgAxAFwATQBJAEMAUgBPAFMAfgAxAFwATwBmAGYAaQ BjAGUAMQAyAFwAVwBJAE4AVwBPAFIARAAuAEUAWABFAAAARgAAABAAAAAEAAAAAQAAA EYAAAAgAAAAEgAAAEkAYwBvAG4ATwBuAGwAeQAAAAAADgAAABQAAAAAAAAAEAAAABQA AAA="; #endregion using (BinaryWriter writer = new BinaryWriter(part.GetStream())) { writer.Write(System.Convert.FromBase64String(iconBytes)); writer.Flush(); } } } 

这是一个适用于大多数类型的代码,但仅适用于Windows机器,因为它需要OLE技术。 事实上,由于OLE的亲密性,它最终取决于你的机器的配置方式,所以你需要尝试一下。

这是一个创建.docx文件的示例代码:

 // 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; } 

这里是实用程序代码,它将从输入文件创建包和图像(EMF)文件。 现在,对于PDF,此代码可能会失败(就像我说的,这取决于您是否安装了Adobe Reader,其版本等)。 如果它在OleCreateFromFile上失败,那么您可以尝试创建/添加名为’PackageOnFileDrop’的注册表项,如下所示:

 HKEY_CLASSES_ROOT\AcroExch.Document.DC\PackageOnFileDrop 

我不确定为什么PDF文件不直接支持OleCreateFromFile (暗装,如果你已经安装了Acrobat Reader,这全部由Adobe的COM服务器提供商AcroRd32.exe处理),我认为它可能是一个安全function,我不知道Word如何规避这个……

 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)); // note 1: if you get 'Use of Ole1 services requiring DDE windows is disabled' error, make sure the executing thread is STA // // note 2: if you want packager to succeed on PDF files instead of reporting 0x8000ffff (E_UNEXPECTED), make sure // there exists a key named "PackageOnFileDrop", like this: HKEY_CLASSES_ROOT\AcroExch.Document.DC\PackageOnFileDrop // IDataObject ps; // from System.Runtime.InteropServices.ComTypes CheckHr(OleCreateFromFile( Guid.Empty, inputFile, typeof(IDataObject).GUID, 0, IntPtr.Zero, IntPtr.Zero, storage, out ps)); var format = new FORMATETC(); format.cfFormat = CF_ENHMETAFILE; format.dwAspect = DVASPECT.DVASPECT_CONTENT; format.lindex = -1; format.tymed = TYMED.TYMED_ENHMF; STGMEDIUM medium; ps.GetData(ref format, out medium); CopyEnhMetaFile(medium.unionmember, outputImageFile); DeleteEnhMetaFile(medium.unionmember); storage.Commit(0); Marshal.FinalReleaseComObject(ps); Marshal.FinalReleaseComObject(storage); } private static void CheckHr(int hr) { if (hr != 0) throw new Win32Exception(hr); } [InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000000B-0000-0000-C000-000000000046")] private interface IStorage { void _VtblGap1_6(); // we only need Commit void Commit(int grfCommitFlags); } [DllImport("ole32.dll")] private static extern int StgCreateStorageEx( [MarshalAs(UnmanagedType.LPWStr)] string pwcsName, int grfMode, int stgfmt, int grfAttrs, IntPtr pStgOptions, IntPtr reserved2, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IStorage ppObjectOpen); [DllImport("ole32.dll")] private static extern int OleCreateFromFile( [MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string lpszFileName, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, int renderopt, IntPtr lpFormatEtc, IntPtr pClientSite, IStorage pStg, out IDataObject ppStg ); [DllImport("gdi32.dll", SetLastError = true)] private static extern bool DeleteEnhMetaFile(IntPtr hemf); [DllImport("gdi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, string lpszFile); private const int CF_ENHMETAFILE = 14; private const int STGM_READWRITE = 2; private const int STGM_SHARE_EXCLUSIVE = 0x10; private const int STGM_CREATE = 0x1000; private const int STGFMT_DOCFILE = 5; }