1

私はこの投稿でc#変換されたコードを利用しようとしています: C#でのOLEIStorageファイルハンドルのリリース

この投稿では、OPは、pinvokeを使用してIStorageインターフェイスとIOleObjectインターフェイス、およびさまざまなメソッドを宣言するカスタムクラスOLE32を作成したようです。私も同じことをしました。私の問題は、OLE32.OleCreateFromFileを呼び出そうとすると、返される値が-2147467242になることです。

この戻り値は16進数で0x80004016に変換されます。これは、私が見つけたすべてのことによると、次のエラーです。

DDEウィンドウを必要とするOle1サービスの使用が無効になっている

メソッドはIOleObjectを吐き出す必要がありますが、代わりにpOleはnullであり、これに続くメソッドは失敗します。

なぜこのエラーが発生するのか、どうすれば修正できるのか、誰か知っていますか?以下に、完全なコードとOLE32クラスを含めました。

方法:

   public static string ExportOleFile(string _inputFileName, string oleOutputFileName, string emfOutputFileName)
    {
        StringBuilder resultString = new StringBuilder();

        string newInput = MultibyteToUnicodeNETOnly(_inputFileName, 1252); 


        OLE32.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
        );

        resultString.AppendLine("CreateStorageEx Result: " + result.ToString());

       var CLSID_NULL = Guid.Empty;

        OLE32.IOleObject pOle;
        result = OLE32.OleCreateFromFile(
            ref CLSID_NULL,
            _inputFileName,
            ref OLE32.IID_IOleObject,
            (uint)OLE32.OLERENDER.OLERENDER_NONE,
            IntPtr.Zero,
            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();

    }

OLE32.cs:

  public static class OLE32
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct STGOPTIONS
        {
            ushort usVersion;
            ushort reserved;
            ulong ulSectorSize;
            [MarshalAsAttribute(UnmanagedType.LPWStr)]
            public string pwcsTemplateFile;
        };

        public enum OLERENDER
        {
            OLERENDER_NONE = 0,
            OLERENDER_DRAW = 1,
            OLERENDER_FORMAT = 2,
            OLERENDER_ASIS = 3
        }

        internal enum CLIPFORMAT : int
        {
            CF_TEXT = 1,
            CF_BITMAP = 2,
            CF_METAFILEPICT = 3,
            CF_SYLK = 4,
            CF_DIF = 5,
            CF_TIFF = 6,
            CF_OEMTEXT = 7,
            CF_DIB = 8,
            CF_PALETTE = 9,
            CF_PENDATA = 10,
            CF_RIFF = 11,
            CF_WAVE = 12,
            CF_UNICODETEXT = 13,
            CF_ENHMETAFILE = 14,
            CF_HDROP = 15,
            CF_LOCALE = 16,
            CF_MAX = 17,
            CF_OWNERDISPLAY = 0x80,
            CF_DSPTEXT = 0x81,
            CF_DSPBITMAP = 0x82,
            CF_DSPMETAFILEPICT = 0x83,
            CF_DSPENHMETAFILE = 0x8E,
        }

        internal enum STGFMT : int
        {
            STGFMT_STORAGE = 0,
            STGFMT_FILE = 3,
            STGFMT_ANY = 4,
            STGFMT_DOCFILE = 5
        }

        [Flags]
        internal enum STGM : int
        {
            STGM_READ = 0x0,
            STGM_WRITE = 0x1,
            STGM_READWRITE = 0x2,
            STGM_SHARE_DENY_NONE = 0x40,
            STGM_SHARE_DENY_READ = 0x30,
            STGM_SHARE_DENY_WRITE = 0x20,
            STGM_SHARE_EXCLUSIVE = 0x10,
            STGM_PRIORITY = 0x40000,
            STGM_CREATE = 0x1000,
            STGM_CONVERT = 0x20000,
            STGM_FAILIFTHERE = 0x0,
            STGM_DIRECT = 0x0,
            STGM_TRANSACTED = 0x10000,
            STGM_NOSCRATCH = 0x100000,
            STGM_NOSNAPSHOT = 0x200000,
            STGM_SIMPLE = 0x8000000,
            STGM_DIRECT_SWMR = 0x400000,
            STGM_DELETEONRELEASE = 0x4000000
        }

        public enum STGC
        {
            DEFAULT = 0,
            OVERWRITE = 1,
            ONLYIFCURRENT = 2,
            DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,
            CONSOLIDATE = 8
        }


        public static Guid IID_IDataObject = new Guid("{0000010e-0000-0000-C000-000000000046}");

        public static Guid IID_IOleObject = new Guid("{00000112-0000-0000-C000-000000000046}");

        public static Guid IID_IStorage = new Guid("0000000B-0000-0000-C000-000000000046");



        [DllImport("ole32.dll")]
        public static extern int StgCreateStorageEx([MarshalAs(UnmanagedType.LPWStr)] string
           pwcsName, int grfMode, int stgfmt, int grfAttrs, IntPtr pStgOptions, IntPtr reserved2, ref Guid riid,
           out IStorage ppObjectOpen);


        [DllImport("ole32.dll")]
        public static extern int OleCreateFromFile([In] ref Guid rclsid,
           [MarshalAs(UnmanagedType.LPWStr)] string lpszFileName, ref Guid riid,
           uint renderopt, IntPtr pFormatEtc, IOleClientSite pClientSite,
           IStorage pStg, out IOleObject ppvObj);

        [DllImport("ole32.dll")]
        public static extern int OleRun([MarshalAs(UnmanagedType.IUnknown)] object pUnknown);


        [ComImport]
        [Guid("00000118-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IOleClientSite
        {
            void SaveObject();
            void GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk);
            void GetContainer(ref object ppContainer);
            void ShowObject();
            void OnShowWindow(bool fShow);
            void RequestNewObjectLayout();
        }




        [ComImport]
        [Guid("0000000b-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IStorage
        {
            void CreateStream(
                /* [string][in] */ string pwcsName,
                /* [in] */ uint grfMode,
                /* [in] */ uint reserved1,
                /* [in] */ uint reserved2,
                /* [out] */ out IStream ppstm);

            void OpenStream(
                /* [string][in] */ string pwcsName,
                /* [unique][in] */ IntPtr reserved1,
                /* [in] */ uint grfMode,
                /* [in] */ uint reserved2,
                /* [out] */ out IStream ppstm);

            void CreateStorage(
                /* [string][in] */ string pwcsName,
                /* [in] */ uint grfMode,
                /* [in] */ uint reserved1,
                /* [in] */ uint reserved2,
                /* [out] */ out IStorage ppstg);

            void OpenStorage(
                /* [string][unique][in] */ string pwcsName,
                /* [unique][in] */ IStorage pstgPriority,
                /* [in] */ uint grfMode,
                /* [unique][in] */ IntPtr snbExclude,
                /* [in] */ uint reserved,
                /* [out] */ out IStorage ppstg);

            void CopyTo(
                /* [in] */ uint ciidExclude,
                /* [size_is][unique][in] */ Guid rgiidExclude, // should this be an array?
                /* [unique][in] */ IntPtr snbExclude,
                /* [unique][in] */ IStorage pstgDest);

            void MoveElementTo(
                /* [string][in] */ string pwcsName,
                /* [unique][in] */ IStorage pstgDest,
                /* [string][in] */ string pwcsNewName,
                /* [in] */ uint grfFlags);

            void Commit(
                /* [in] */ uint grfCommitFlags);

            void Revert();

            void EnumElements(
                /* [in] */ uint reserved1,
                /* [size_is][unique][in] */ IntPtr reserved2,
                /* [in] */ uint reserved3,
                /* [out] */ out IEnumSTATSTG ppenum);

            void DestroyElement(
                /* [string][in] */ string pwcsName);

            void RenameElement(
                /* [string][in] */ string pwcsOldName,
                /* [string][in] */ string pwcsNewName);

            void SetElementTimes(
                /* [string][unique][in] */ string pwcsName,
                /* [unique][in] */ System.Runtime.InteropServices.FILETIME pctime,
                /* [unique][in] */ System.Runtime.InteropServices.FILETIME patime,
                /* [unique][in] */ System.Runtime.InteropServices.FILETIME pmtime);

            void SetClass(
                /* [in] */ Guid clsid);

            void SetStateBits(
                /* [in] */ uint grfStateBits,
                /* [in] */ uint grfMask);

            void Stat(
                /* [out] */ out System.Runtime.InteropServices.STATSTG pstatstg,
                /* [in] */ uint grfStatFlag);

        }

        [ComImport]
        [Guid("00000112-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IOleObject
        {
            void SetClientSite(IOleClientSite pClientSite);
            void GetClientSite(ref IOleClientSite ppClientSite);
            void SetHostNames(object szContainerApp, object szContainerObj);
            void Close(uint dwSaveOption);
            void SetMoniker(uint dwWhichMoniker, object pmk);
            void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
            void InitFromData(IDataObject pDataObject, bool fCreation, uint dwReserved);
            void GetClipboardData(uint dwReserved, ref IDataObject ppDataObject);
            void DoVerb(uint iVerb, uint lpmsg, object pActiveSite, uint lindex, uint hwndParent, uint lprcPosRect);
            void EnumVerbs(ref object ppEnumOleVerb);
            void Update();
            void IsUpToDate();
            void GetUserClassID(uint pClsid);
            void GetUserType(uint dwFormOfType, uint pszUserType);
            void SetExtent(uint dwDrawAspect, uint psizel);
            void GetExtent(uint dwDrawAspect, uint psizel);
            void Advise(object pAdvSink, uint pdwConnection);
            void Unadvise(uint dwConnection);
            void EnumAdvise(ref object ppenumAdvise);
            void GetMiscStatus(uint dwAspect, uint pdwStatus);
            void SetColorScheme(object pLogpal);
        };

        [ComImport]
        [Guid("0000000d-0000-0000-C000-000000000046")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IEnumSTATSTG
        {
            // The user needs to allocate an STATSTG array whose size is celt.
            [PreserveSig]
            uint
            Next(
            uint celt,
            [MarshalAs(UnmanagedType.LPArray), Out]
    System.Runtime.InteropServices.STATSTG[] rgelt,
            out uint pceltFetched
            );

            void Skip(uint celt);

            void Reset();

            [return: MarshalAs(UnmanagedType.Interface)]
            IEnumSTATSTG Clone();
        }


        [ComImport, Guid("0000000c-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IStream
        {
            void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbRead);
            void Write([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv, uint cb, out uint pcbWritten);
            void Seek(long dlibMove, uint dwOrigin, out long plibNewPosition);
            void SetSize(long libNewSize);
            void CopyTo(IStream pstm, long cb, out long pcbRead, out long pcbWritten);
            void Commit(uint grfCommitFlags);
            void Revert();
            void LockRegion(long libOffset, long cb, uint dwLockType);
            void UnlockRegion(long libOffset, long cb, uint dwLockType);
            void Stat(out System.Runtime.InteropServices.STATSTG pstatstg, uint grfStatFlag);
            void Clone(out IStream ppstm);
        }


        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000010E-0000-0000-C000-000000000046")]
        public interface IDataObject
        {
            void GetData([In] ref FORMATETC format, out STGMEDIUM medium);
            void GetDataHere([In] ref FORMATETC format, ref STGMEDIUM medium);
            [PreserveSig]
            int QueryGetData([In] ref FORMATETC format);
            [PreserveSig]
            int GetCanonicalFormatEtc([In] ref FORMATETC formatIn, out FORMATETC formatOut);
            void SetData([In] ref FORMATETC formatIn, [In] ref STGMEDIUM medium, [MarshalAs(UnmanagedType.Bool)] bool release);
            IEnumFORMATETC EnumFormatEtc(DATADIR direction);
            [PreserveSig]
            int DAdvise([In] ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection);
            void DUnadvise(int connection);
            [PreserveSig]
            int EnumDAdvise(out IEnumSTATDATA enumAdvise);
        }











    }
4

1 に答える 1

2

コードに明らかに問題はありません。欠落している宣言を追加した後、.NET 3.5と4.5の両方でpdo.GetData()呼び出しまで実行できました。それを超えて続行するための正しい種類の入力ファイルがありませんでした。

0x80004016エラーコードの適切な説明は1つだけです。これは、このコードを実行するスレッドがCOINIT_DISABLE_OLE1DDEオプションを指定してOleInitializeEx()を呼び出した場合に発生します。.NETはこれを行いません。したがって、スレッドはネイティブコードによって開始され、このマネージコードに移行したと推測する必要があります。これはコードの種類に適合し、通常はC++で記述されます。

そのOleInitializeEx呼び出しを探し出し、変更する必要があります。それが難しい場合は、独自のスレッドを開始してこのコードを実行することを検討してください。そうすれば、呼び出し元のネイティブスレッドの状態が悪いことによる影響を受けません。

于 2013-02-18T01:07:55.903 に答える