Приветствую!
Возможно не совсем тема раздела, но не нашел ничего более подходящего
Проблема следующая. Создаю dll-ку, которая должна работать с ole-объектами
Основной класс
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52.
public class Helper
{
[STAThread]
public static string ExportOleFile(string inputFileName, string oleOutputFileName, string emfOutputFileName)
{
try
{
OLE32.CoUninitialize();
OLE32.CoInitializeEx(IntPtr.Zero, OLE32.CoInit.ApartmentThreaded); //COINIT_APARTMENTTHREADED
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
);
if (result != 0) result.ToString("X")
var CLSID_NULL = Guid.Empty;
OLE32.IOleObject pOle;
result = OLE32.OleCreateFromFile(
ref CLSID_NULL,
inputFileName,
ref OLE32.IID_IDataObject,
(uint)OLE32.OLERENDER.OLERENDER_NONE,
IntPtr.Zero,
null,
storage,
out pOle
);
if (result != 0) return result.ToString("X")
result = OLE32.OleRun(pOle);
...
}
catch (Exception ex)
{
resultString.AppendLine(ex.ToString());
return resultString.ToString();
}
return resultString.ToString();
}
}
OLE32
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353. 354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367. 368. 369. 370. 371. 372. 373. 374. 375. 376. 377. 378. 379. 380. 381. 382. 383. 384. 385. 386. 387. 388. 389. 390. 391. 392. 393. 394. 395. 396. 397. 398. 399. 400. 401. 402. 403. 404. 405. 406. 407. 408. 409. 410. 411. 412. 413. 414. 415. 416. 417. 418. 419. 420.
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 enum CoInit
{
MultiThreaded = 0x0,
ApartmentThreaded = 0x2,
DisableOLE1DDE = 0x4,
SpeedOverMemory = 0x8
}
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", PreserveSig = false)]
[return: MarshalAs(UnmanagedType.IUnknown)]
public static extern object OleGetClipboard();
[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 OleCreateFromFile([In] ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)] string lpszFileName, [In] ref Guid riid,
uint renderopt, [In] ref FORMATETC pFormatEtc, IOleClientSite pClientSite,
IStorage pStg, out IOleObject ppvObj);
[DllImport("ole32.dll")]
public static extern int OleCreateFromFileEx([In] ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)] string lpszFileName, [In] ref Guid riid,
uint dwFlags, uint renderopt, uint cFormats, uint rgAdvf, FORMATETC[]
rgFormatEtc, IAdviseSink pAdviseSink, [Out] uint[] rgdwConnection,
IOleClientSite pClientSite, IStorage pStg,
[MarshalAs(UnmanagedType.IUnknown)] out object ppvObj);
[DllImport("ole32.dll")]
public static extern int OleSetContainedObject([MarshalAs(UnmanagedType.IUnknown)] object pUnk, bool fContained);
[DllImport("ole32.dll")]
public static extern int OleRun([MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
[DllImport("Ole32.dll", ExactSpelling = true, EntryPoint = "CoInitialize",
CallingConvention = CallingConvention.StdCall, SetLastError = false)]
public static extern int CoInitialize(
IntPtr pvReserved
);
[DllImport("Ole32.dll", ExactSpelling = true, EntryPoint = "CoInitializeEx", CallingConvention = CallingConvention.StdCall, SetLastError = false, PreserveSig = false)]
public static extern void CoInitializeEx(IntPtr pvReserved, CoInit coInit);
[DllImport("Ole32.dll", ExactSpelling = true, EntryPoint = "CoUninitialize",
CallingConvention = CallingConvention.StdCall, SetLastError = false)]
public static extern int CoUninitialize();
[DllImport("Ole32.dll", ExactSpelling = true, EntryPoint = "CoInitializeSecurity",
CallingConvention = CallingConvention.StdCall, SetLastError = false)]
static extern int CoInitializeSecurity(
IntPtr pVoid,
uint cAuthSvc,
IntPtr asAuthSvc,
IntPtr pReserved1,
uint dwAuthnLevel,
uint dwImpLevel,
IntPtr pAuthList,
uint dwCapabilities,
IntPtr pReserved3
);
[DllImport("ole32.dll")]
public extern static int CreateILockBytesOnHGlobal(IntPtr hGlobal, [MarshalAs(UnmanagedType.Bool)] bool fDeleteOnRelease, out ILockBytes ppLkbyt);
[DllImport("ole32.dll")]
public extern static int StgCreateDocfileOnILockBytes(ILockBytes plkbyt, StgmConstants grfMode, int reserved, out IStorage ppstgOpen);
[DllImport("ole32.dll")]
public static extern int OleCreateFromFile([In] ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)] string lpszFileName, [In] ref Guid riid,
uint renderopt, [In] ref FORMATETC pFormatEtc, IOleClientSite pClientSite,
IStorage pStg, [MarshalAs(UnmanagedType.IUnknown)] out object ppvObj);
[DllImport("ole32.dll")]
public static extern int CreateStreamOnHGlobal(IntPtr hGlobal, bool fDeleteOnRelease,
out System.Runtime.InteropServices.ComTypes.IStream ppstm);
[DllImport("ole32.dll")]
public static extern int OleLoadFromStream(IStream pStm,
[In] ref Guid riid,
out IOleObject ppvObj);
[Flags]
public enum StgmConstants
{
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
}
[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();
}
[ComVisible(false)]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0000000A-0000-0000-C000-000000000046")]
public interface ILockBytes
{
void ReadAt(long ulOffset, IntPtr pv, int cb, out UIntPtr pcbRead);
void WriteAt(long ulOffset, IntPtr pv, int cb, out UIntPtr pcbWritten);
void Flush();
void SetSize(long cb);
void LockRegion(long libOffset, long cb, int dwLockType);
void UnlockRegion(long libOffset, long cb, int dwLockType);
void Stat(out System.Runtime.InteropServices.STATSTG pstatstg, int grfStatFlag);
}
[ComImport]
[Guid("0000000b-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStorage
{
void CreateStream(
/* [string][in] */ string pwcsName,
/* [in] */ StgmConstants 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);
}
}
проблема с вызовом OleCreateFromFile.
На Win7 отрабатывает корректно
На WinXP:
- если я делаю приложение WinForms, из которого вызываю Helper.ExportOleFile(oleFile, binFile, emfFile) - тоже корректно
- а вот если сделать консольное приложение и вызвать тот же самый Helper.ExportOleFile(oleFile, binFile, emfFile), то OleCreateFromFile возвращает: -2147221497 (80040007) Объект не инициализирован.
Кто-нибудь может подсказать в чем причина?
|