PageRenderTime 31ms CodeModel.GetById 18ms app.highlight 9ms 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
 25using System;
 26using System.Runtime.InteropServices;
 27using Microsoft.Win32.SafeHandles;
 28using System.ComponentModel;
 29
 30namespace CSRegFreeCOMClient
 31{
 32    class Program
 33    {
 34        static string manifestPath;
 35
 36        [STAThread]
 37        static void Main(string[] args)
 38        {
 39            try
 40            {
 41                // If the application is run with args, the activation context
 42                // will be activated by specifying manifest file manually.
 43                if (args.Length > 0)
 44                {
 45                    Console.WriteLine("------ Activate activation context manually ------");
 46
 47                    Console.WriteLine("Please input the full path of manifest file:");
 48                    manifestPath = Console.ReadLine();
 49
 50                    ActivateActivationContext(ConsumeCOMComponent, manifestPath);
 51                }
 52                // If the application is run without args, the activation context
 53                // will be activated by searching the manifest file automatically.
 54                else
 55                {
 56                    Console.WriteLine("------Activate activation context automatically------");
 57
 58                    ConsumeCOMComponent();
 59                }
 60            }
 61            catch (Exception ex)
 62            {
 63                Console.WriteLine(ex.Message);
 64            }
 65
 66            Console.WriteLine("Press any key to continue...");
 67            Console.ReadKey();
 68        }
 69
 70        /// <summary>
 71        /// Consumes the COM component.
 72        /// </summary>
 73        static void ConsumeCOMComponent()
 74        {
 75            ATLDllCOMServerLib.SimpleObject simpleObj =
 76                new ATLDllCOMServerLib.SimpleObject();
 77
 78            try
 79            {
 80                // Call the method: HelloWorld, that returns a string.
 81                {
 82                    string strResult = simpleObj.HelloWorld();
 83                    Console.WriteLine("Call HelloWorld => {0}", strResult);
 84                }
 85            }
 86            catch (Exception ex)
 87            {
 88                Console.WriteLine("The server throws the error: {0}", ex.Message);
 89                if (ex.InnerException != null)
 90                {
 91                    Console.WriteLine("Description: {0}", ex.InnerException.Message);
 92                }
 93            }
 94
 95            Marshal.FinalReleaseComObject(simpleObj);
 96        }
 97
 98        /// <summary>
 99        /// Activate activation context according to the given manifest file, 
100        /// and the specified action.
101        /// </summary>
102        /// <param name="actoinToDo">
103        /// The method that will be executed if the activation succeed.
104        /// </param>
105        /// <param name="manifestPath">
106        /// The full path of manifest file.
107        /// </param>
108        static void ActivateActivationContext(Action actoinToDo, string manifestPath)
109        {
110            ACTCTX ac = new ACTCTX();
111            ac.cbSize = Marshal.SizeOf(typeof(ACTCTX));
112            ac.lpSource = manifestPath;
113            ac.dwFlags = 0;
114
115            IntPtr cookie;
116            SafeActCtxHandle hActCtx = NativeMethod.CreateActCtx(ref ac);
117            if (!hActCtx.IsInvalid)
118            {
119                try
120                {
121                    // Activate the activation context.
122                    if (NativeMethod.ActivateActCtx(hActCtx, out cookie))
123                    {
124                        try
125                        {
126                            actoinToDo();
127                        }
128                        finally
129                        {
130                            // Deactivate the activation context.
131                            NativeMethod.DeactivateActCtx(0, cookie);
132                        }
133                    }
134                    else
135                    {
136                        Console.WriteLine("The ActCtx failed to be activated w/err {0}",
137                            Marshal.GetLastWin32Error());
138                    }
139                }
140                finally
141                {
142                    hActCtx.Dispose();
143                }
144            }
145            else
146            {
147                Console.WriteLine("The ActCtx failed to be created w/err {0}",
148                    Marshal.GetLastWin32Error());
149            }
150        }
151    }
152
153    /// <summary>
154    /// The class contains native methods.
155    /// </summary>
156    class NativeMethod
157    {
158        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
159        public static extern SafeActCtxHandle CreateActCtx(ref ACTCTX pActCtx);
160
161        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
162        [return: MarshalAs(UnmanagedType.Bool)]
163        public static extern bool ActivateActCtx(SafeActCtxHandle hActCtx, out IntPtr lpCookie);
164
165        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
166        [return: MarshalAs(UnmanagedType.Bool)]
167        public static extern bool DeactivateActCtx(int dwFlags, IntPtr lpCookie);
168
169        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
170        public static extern void ReleaseActCtx(IntPtr hActCtx);
171    }
172
173    class SafeActCtxHandle : SafeHandleZeroOrMinusOneIsInvalid
174    {
175        private SafeActCtxHandle()
176            : base(true)
177        {
178        }
179
180        public SafeActCtxHandle(IntPtr preexistingHandle, bool ownsHandle)
181            : base(ownsHandle)
182        {
183            base.SetHandle(preexistingHandle);
184        }
185
186        protected override bool ReleaseHandle()
187        {
188            NativeMethod.ReleaseActCtx(base.handle);
189            return true;
190        }
191    }
192
193    /// <summary>
194    /// The ACTCTX struct.
195    /// </summary>
196    [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
197    public struct ACTCTX
198    {
199        public int cbSize;
200        public uint dwFlags;
201        public string lpSource;
202        public ushort wProcessorArchitecture;
203        public Int16 wLangId;
204        public string lpAssemblyDirectory;
205        public string lpResourceName;
206        public string lpApplicationName;
207        public IntPtr hModule;
208    }
209}