I am trying to embed pdf files into OPEN XML document. This requires creating *.bin files. I dont want to use automation.
Approach which Ive taken from this question works for all file types Ive tested except *.pdf.
For some reason pdf files always get the result from OleCreateFromFile(..) to be 0x80004005 and the pOle is NULL.
I am new on the field of invoking and OLE. What could be a reason for this approach not working for PDF? (I have newest Adobe Reader, Win8, invoking into Ole32.dll, projects build target is x86 and Ive test to call CoUninitialize() and CoInitializeEx((System.IntPtr)null, OLE32.CoInit.ApartmentThreaded), I am able to embed pdf files in MSWORD application).
Here is a function that I use for it:
public static string ExportOleFile(string _inputFileName, string oleOutputFileName, string emfOutputFileName)
{
StringBuilder resultString = new StringBuilder();
string newInput = MultibyteToUnicodeNETOnly(_inputFileName, 1252);
Microsoft.VisualStudio.OLE.Interop.IStorage storage;
var result = OLE32.StgCreateStorageEx(oleOutputFileName,
Convert.ToInt32(OLE32.STGM.STGM_READWRITE | OLE32.STGM.STGM_SHARE_EXCLUSIVE | OLE32.STGM.STGM_CREATE | OLE32.STGM.STGM_TRANSACTED),
Convert.ToInt32(OLE32.STGFMT.STGFMT_DOCFILE),
0,
IntPtr.Zero,
IntPtr.Zero,
ref OLE32.IID_IStorage,
out storage
);//vytvoří bin
resultString.AppendLine("CreateStorageEx Result: " + result.ToString());
var CLSID_NULL = Guid.Empty;
Microsoft.VisualStudio.OLE.Interop.FORMATETC f = new FORMATETC();
Microsoft.VisualStudio.OLE.Interop.IOleObject pOle;
result = OLE32.OleCreateFromFile(
ref CLSID_NULL,
newInput,
ref OLE32.IID_IOleObject,
(uint)Microsoft.VisualStudio.OLE.Interop.OLERENDER.OLERENDER_NONE,
ref f,
null,
storage,
out pOle
);
resultString.AppendLine("OleCreateFromFile Result: " + result.ToString());
try
{
result = OLE32.OleRun(pOle);
}
catch (Exception ex)
{
resultString.AppendLine(ex.ToString());
return resultString.ToString();
}
resultString.AppendLine("OleRun Result: " + result.ToString());
try
{
IntPtr unknownFromOle = Marshal.GetIUnknownForObject(pOle);
IntPtr unknownForDataObj;
Marshal.QueryInterface(unknownFromOle, ref OLE32.IID_IDataObject, out unknownForDataObj);
var pdo = Marshal.GetObjectForIUnknown(unknownForDataObj) as System.Runtime.InteropServices.ComTypes.IDataObject;
var fetc = new System.Runtime.InteropServices.ComTypes.FORMATETC();
fetc.cfFormat = (short)OLE32.CLIPFORMAT.CF_ENHMETAFILE;
fetc.dwAspect = System.Runtime.InteropServices.ComTypes.DVASPECT.DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.ptd = IntPtr.Zero;
fetc.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_ENHMF;
var stgm = new System.Runtime.InteropServices.ComTypes.STGMEDIUM();
stgm.unionmember = IntPtr.Zero;
stgm.tymed = System.Runtime.InteropServices.ComTypes.TYMED.TYMED_ENHMF;
pdo.GetData(ref fetc, out stgm);
var hemf = GDI32.CopyEnhMetaFile(stgm.unionmember, emfOutputFileName);
storage.Commit((int)OLE32.STGC.DEFAULT);
pOle.Close(0);
GDI32.DeleteEnhMetaFile(stgm.unionmember);
GDI32.DeleteEnhMetaFile(hemf);
}
catch (Exception ex)
{
resultString.AppendLine(ex.ToString());
return resultString.ToString();
}
return resultString.ToString();
}