PageRenderTime 5568ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/Visual Studio 2008/CSRegFreeCOMClient/Program.cs

#
C# | 209 lines | 140 code | 20 blank | 49 comment | 5 complexity | 680ec11a13de1fb99aa1652ac416c237 MD5 | raw file
  1. /****************************** Module Header ******************************\
  2. * Module Name: Program.cs
  3. * Project: CSRegFreeCOMClient
  4. * Copyright (c) Microsoft Corporation.
  5. *
  6. * Registration-free COM is a mechanism available on the Microsoft Windows XP
  7. * (SP2 for .NET Framework-based components), Microsoft Windows Server 2003
  8. * and newer platforms. As the name suggests, the mechanism enables easy (e.g.
  9. * XCOPY) deployment of COM components to a machine without the need to
  10. * register them.
  11. *
  12. * The CSRegFreeCOMClient sample demonstrates how to create a registration-
  13. * free COM from the aspect of .NET Framework based client, so that the client
  14. * can consume existing COM server as if the COM server is Registration-free.
  15. *
  16. * This source is subject to the Microsoft Public License.
  17. * See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
  18. * All other rights reserved.
  19. *
  20. * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  21. * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
  22. * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
  23. \***************************************************************************/
  24. using System;
  25. using System.Runtime.InteropServices;
  26. using Microsoft.Win32.SafeHandles;
  27. using System.ComponentModel;
  28. namespace CSRegFreeCOMClient
  29. {
  30. class Program
  31. {
  32. static string manifestPath;
  33. [STAThread]
  34. static void Main(string[] args)
  35. {
  36. try
  37. {
  38. // If the application is run with args, the activation context
  39. // will be activated by specifying manifest file manually.
  40. if (args.Length > 0)
  41. {
  42. Console.WriteLine("------ Activate activation context manually ------");
  43. Console.WriteLine("Please input the full path of manifest file:");
  44. manifestPath = Console.ReadLine();
  45. ActivateActivationContext(ConsumeCOMComponent, manifestPath);
  46. }
  47. // If the application is run without args, the activation context
  48. // will be activated by searching the manifest file automatically.
  49. else
  50. {
  51. Console.WriteLine("------Activate activation context automatically------");
  52. ConsumeCOMComponent();
  53. }
  54. }
  55. catch (Exception ex)
  56. {
  57. Console.WriteLine(ex.Message);
  58. }
  59. Console.WriteLine("Press any key to continue...");
  60. Console.ReadKey();
  61. }
  62. /// <summary>
  63. /// Consumes the COM component.
  64. /// </summary>
  65. static void ConsumeCOMComponent()
  66. {
  67. ATLDllCOMServerLib.SimpleObject simpleObj =
  68. new ATLDllCOMServerLib.SimpleObject();
  69. try
  70. {
  71. // Call the method: HelloWorld, that returns a string.
  72. {
  73. string strResult = simpleObj.HelloWorld();
  74. Console.WriteLine("Call HelloWorld => {0}", strResult);
  75. }
  76. }
  77. catch (Exception ex)
  78. {
  79. Console.WriteLine("The server throws the error: {0}", ex.Message);
  80. if (ex.InnerException != null)
  81. {
  82. Console.WriteLine("Description: {0}", ex.InnerException.Message);
  83. }
  84. }
  85. Marshal.FinalReleaseComObject(simpleObj);
  86. }
  87. /// <summary>
  88. /// Activate activation context according to the given manifest file,
  89. /// and the specified action.
  90. /// </summary>
  91. /// <param name="actoinToDo">
  92. /// The method that will be executed if the activation succeed.
  93. /// </param>
  94. /// <param name="manifestPath">
  95. /// The full path of manifest file.
  96. /// </param>
  97. static void ActivateActivationContext(Action actoinToDo, string manifestPath)
  98. {
  99. ACTCTX ac = new ACTCTX();
  100. ac.cbSize = Marshal.SizeOf(typeof(ACTCTX));
  101. ac.lpSource = manifestPath;
  102. ac.dwFlags = 0;
  103. IntPtr cookie;
  104. SafeActCtxHandle hActCtx = NativeMethod.CreateActCtx(ref ac);
  105. if (!hActCtx.IsInvalid)
  106. {
  107. try
  108. {
  109. // Activate the activation context.
  110. if (NativeMethod.ActivateActCtx(hActCtx, out cookie))
  111. {
  112. try
  113. {
  114. actoinToDo();
  115. }
  116. finally
  117. {
  118. // Deactivate the activation context.
  119. NativeMethod.DeactivateActCtx(0, cookie);
  120. }
  121. }
  122. else
  123. {
  124. Console.WriteLine("The ActCtx failed to be activated w/err {0}",
  125. Marshal.GetLastWin32Error());
  126. }
  127. }
  128. finally
  129. {
  130. hActCtx.Dispose();
  131. }
  132. }
  133. else
  134. {
  135. Console.WriteLine("The ActCtx failed to be created w/err {0}",
  136. Marshal.GetLastWin32Error());
  137. }
  138. }
  139. }
  140. /// <summary>
  141. /// The class contains native methods.
  142. /// </summary>
  143. class NativeMethod
  144. {
  145. [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  146. public static extern SafeActCtxHandle CreateActCtx(ref ACTCTX pActCtx);
  147. [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  148. [return: MarshalAs(UnmanagedType.Bool)]
  149. public static extern bool ActivateActCtx(SafeActCtxHandle hActCtx, out IntPtr lpCookie);
  150. [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  151. [return: MarshalAs(UnmanagedType.Bool)]
  152. public static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie);
  153. [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
  154. public static extern void ReleaseActCtx(IntPtr hActCtx);
  155. }
  156. class SafeActCtxHandle : SafeHandleZeroOrMinusOneIsInvalid
  157. {
  158. private SafeActCtxHandle()
  159. : base(true)
  160. {
  161. }
  162. public SafeActCtxHandle(IntPtr preexistingHandle, bool ownsHandle)
  163. : base(ownsHandle)
  164. {
  165. base.SetHandle(preexistingHandle);
  166. }
  167. protected override bool ReleaseHandle()
  168. {
  169. NativeMethod.ReleaseActCtx(base.handle);
  170. return true;
  171. }
  172. }
  173. /// <summary>
  174. /// The ACTCTX struct.
  175. /// </summary>
  176. [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
  177. public struct ACTCTX
  178. {
  179. public int cbSize;
  180. public uint dwFlags;
  181. public string lpSource;
  182. public ushort wProcessorArchitecture;
  183. public Int16 wLangId;
  184. public string lpAssemblyDirectory;
  185. public string lpResourceName;
  186. public string lpApplicationName;
  187. public IntPtr hModule;
  188. }
  189. }