https://docs.microsoft.com/en-us/archive/blogs/brian_jones/embedding-any-file-type-like-で説明されているOLE手法を使用して、PDFファイルをWord文書に埋め込もうとしています 。 pdf-in-an-open-xml-file
プロジェクト全体が1つの場所にあり、1つの障害物を除いてほとんどそこにあるように、C#で提供されるC++コードを実装しようとしました。生成されたOLEオブジェクトのバイナリデータをWordドキュメントにフィードしようとすると、IOExceptionが発生します。
IOException:別のプロセスによって使用されているため、プロセスはファイル'C:\ Whereever\Whatever.pdf.bin'にアクセスできません。
.binファイル(以下の「oleOutputFileName」)を開くファイルハンドルがあり、それを取り除く方法がわかりません。私はCOMについて多くのことを知りません-私はここでそれを翼にしています-そして私はファイルハンドルがどこにあるか、またはそれを解放する方法を知りません。
これが私のC#化されたコードがどのように見えるかです。私は何が欠けていますか?
public void ExportOleFile(string oleOutputFileName, string emfOutputFileName)
{
OLE32.IStorage storage;
var result = OLE32.StgCreateStorageEx(
oleOutputFileName,
OLE32.STGM.STGM_READWRITE | OLE32.STGM.STGM_SHARE_EXCLUSIVE | OLE32.STGM.STGM_CREATE | OLE32.STGM.STGM_TRANSACTED,
OLE32.STGFMT.STGFMT_DOCFILE,
0,
IntPtr.Zero,
IntPtr.Zero,
ref OLE32.IID_IStorage,
out storage
);
var CLSID_NULL = Guid.Empty;
OLE32.IOleObject pOle;
result = OLE32.OleCreateFromFile(
ref CLSID_NULL,
_inputFileName,
ref OLE32.IID_IOleObject,
OLE32.OLERENDER.OLERENDER_NONE,
IntPtr.Zero,
null,
storage,
out pOle
);
result = OLE32.OleRun(pOle);
IntPtr unknownFromOle = Marshal.GetIUnknownForObject(pOle);
IntPtr unknownForDataObj;
Marshal.QueryInterface(unknownFromOle, ref OLE32.IID_IDataObject, out unknownForDataObj);
var pdo = Marshal.GetObjectForIUnknown(unknownForDataObj) as IDataObject;
var fetc = new FORMATETC();
fetc.cfFormat = (short)OLE32.CLIPFORMAT.CF_ENHMETAFILE;
fetc.dwAspect = DVASPECT.DVASPECT_CONTENT;
fetc.lindex = -1;
fetc.ptd = IntPtr.Zero;
fetc.tymed = TYMED.TYMED_ENHMF;
var stgm = new STGMEDIUM();
stgm.unionmember = IntPtr.Zero;
stgm.tymed = TYMED.TYMED_ENHMF;
pdo.GetData(ref fetc, out stgm);
var hemf = GDI32.CopyEnhMetaFile(stgm.unionmember, emfOutputFileName);
storage.Commit((int)OLE32.STGC.STGC_DEFAULT);
pOle.Close(0);
GDI32.DeleteEnhMetaFile(stgm.unionmember);
GDI32.DeleteEnhMetaFile(hemf);
}
更新1:「。binファイル」が意味するファイルを明確にしました。
更新2:私が取り除きたいものは使い捨てではないので、私は「使用中」のブロックを使用していません。(そして完全に正直に言うと、ファイルハンドルを削除するために何をリリースする必要があるのかわかりません。COMは私にとって外国語です。)