CLR and Redemption C# class

Started by stanl, August 22, 2014, 11:48:50 AM

Previous topic - Next topic

stanl

Would like to use the Redemption C# class to bypass the Outlook Security patch but not needing to register the Redemption .dll

Can either Tony or Deana render an opinion if it is even worth investigating?

http://www.dimastr.com/redemption/security.htm#redemptionloader

td

You will have to try it and find out. COM registration has never seemed particularly onerous so the time vs. benefit ratio may not be leaning in the C# class's favor.  Of course, you will have to decide if that ratio works for you.

If you are feeling generous and do investigate, you could let us know the results.  It might be of interest to forum members.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

Quote from: td on August 22, 2014, 01:08:43 PM
You will have to try it and find out. COM registration has never seemed particularly onerous

That would be the 'gotcha' - neither the users or me will have admin rights and therefore cannot register the dlls - otherwise I would have chosen COM.

As for the check it out yourself... I was hoping to spare the BBS of numerous threads on this topic, hoping someone with a little more class expertise could survey the class and determine if it might work with CLR.

ITMT: probably try a generic gmail and SMPT.

td

Quote from: stanl on August 23, 2014, 06:15:27 AM

That would be the 'gotcha' - neither the users or me will have admin rights and therefore cannot register the dlls - otherwise I would have chosen COM.

I guess that is why you have an admin install software.

Quote
As for the check it out yourself... I was hoping to spare the BBS of numerous threads on this topic, hoping someone with a little more class expertise could survey the class and determine if it might work with CLR.

The CLR limitations are documented or described in posts on this forum and any thing else that might become problematic can only be discovered by trying.  There are very few CLR related issues that cannot be resolved by creating an in-memory C# class.  It does require some level of mastery of the C# language and our support does not include training C# programmers. We simply do not have the resources necessary to devote time to that kind of activity nor do we have the resources to provide consulting services.

WinBatch CLR hosting is a powerful tool that allows users to greatly reduce the amount of script writing necessary to perform often complex tasks. However, it does have some limitations that are the result of limitations imposed by MSFT on the CLR interface WinBatch uses.  If a user does have the chops to work beyond those limitations, there is nothing preventing that user from doing so.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

There are techniques for registering COM Automation objects without admin privileges.  I have never used them so I can offer no advice or suggestions.  A Google search might be instructive.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

Hey Stan,

    I took it this far...but hit a snag.  Could probably hack my way through the rest of it but tired and need to quit for now.   Seems to create the object fine but then get an error about not finding the DLL.  Probably a CLROption issue but not sure how that all works.   Thought maybe you would like the code since it may be a day or so before I get back to it.

   I'll mail you a needed file (Sure wish they would bump the size limit here so one could post stuff when needed.)


Jim

Code (winbatch) Select



GoSub Load_Routines

  Home_Path = DirScript()
  Load_Redemption()

  RedemptionLoader = ObjectClrNew( 'Redemption.RedemptionLoader' )

  RedemptionLoader.DllLocation32Bit = "%Home_Path%redemption.dll";

  session = RedemptionLoader.new_RDOSession();

  session.Logon(Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);


RDOSession = 0

Exit



:LOAD_ROUTINES

#DefineSubRoutine Load_Redemption()

;***************************************************************************
;**  Run C# in memory using WinBatch - Use Namespace.Class defined in CSharpeSource
;**
;** Purpose:  Run C# in memory using WinBatch - Using Namespace.Class defined in CSharpeSource
;** Inputs:
;** Outputs: Results in message
;**
;** Developer: Deana Falk 2014.04.14
;***************************************************************************

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Load assemblies into the WinBatch process.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; mscorlib assembly is automatically loaded by WinBatch when the CLR is loaded.

  ObjectClrOption("use","System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")

;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Compiles the c# code in Memory
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  objCSharp = ObjectClrNew('Microsoft.CSharp.CSharpCodeProvider')
  objParams = ObjectClrNew('System.CodeDom.Compiler.CompilerParameters')
  objParams.GenerateInMemory = ObjectType( "VT_BOOL", 1 ) ;TRUE
 
  objParams.ReferencedAssemblies.Add("System.dll")
  objParams.ReferencedAssemblies.Add("Interop.Redemption.dll")

;Make sure the cSharp code includes both namepspace and class that can be later used by ObjectCLRNew
  cSharpSource =               `using System; `:@LF
  cSharpSource = cSharpSource :`using System.Collections.Generic; `:@LF
  cSharpSource = cSharpSource :`using System.ComponentModel; `:@LF
  cSharpSource = cSharpSource :`using System.Text; `:@LF
  cSharpSource = cSharpSource :`using System.IO; `:@LF
  cSharpSource = cSharpSource :`using System.Threading; `:@LF
  cSharpSource = cSharpSource :`using System.Reflection; `:@LF
  cSharpSource = cSharpSource :`using System.Runtime.InteropServices; `:@LF
  cSharpSource = cSharpSource :`using System.Runtime.InteropServices.ComTypes; `:@LF
  cSharpSource = cSharpSource :`using Redemption; `:@LF

  cSharpSource = cSharpSource :`namespace Redemption {`:@LF

  cSharpSource = cSharpSource :`      public static class RedemptionLoader `:@LF
  cSharpSource = cSharpSource :`    { `:@LF
  cSharpSource = cSharpSource :`        #region public methods `:@LF
  cSharpSource = cSharpSource :`        //64 bit dll location - defaults to <assemblydir>\Redemption64.dll `:@LF
  cSharpSource = cSharpSource :`        public static string DllLocation64Bit; `:@LF
  cSharpSource = cSharpSource :`        //32 bit dll location - defaults to <assemblydir>\Redemption.dll `:@LF
  cSharpSource = cSharpSource :`        public static string DllLocation32Bit; `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        //The only creatable RDO object - RDOSession `:@LF
  cSharpSource = cSharpSource :`        public static RDOSession new_RDOSession() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (RDOSession)NewRedemptionObject(new Guid("29AB7A12-B531-450E-8F7A-EA94C2F3C05F")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        //Safe*Item objects `:@LF
  cSharpSource = cSharpSource :`        public static SafeMailItem new_SafeMailItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeMailItem)NewRedemptionObject(new Guid("741BEEFD-AEC0-4AFF-84AF-4F61D15F5526")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeContactItem new_SafeContactItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeContactItem)NewRedemptionObject(new Guid("4FD5C4D3-6C15-4EA0-9EB9-EEE8FC74A91B")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeAppointmentItem new_SafeAppointmentItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeAppointmentItem)NewRedemptionObject(new Guid("620D55B0-F2FB-464E-A278-B4308DB1DB2B")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeTaskItem new_SafeTaskItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeTaskItem)NewRedemptionObject(new Guid("7A41359E-0407-470F-B3F7-7C6A0F7C449A")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeJournalItem new_SafeJournalItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeJournalItem)NewRedemptionObject(new Guid("C5AA36A1-8BD1-47E0-90F8-47E7239C6EA1")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeMeetingItem new_SafeMeetingItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeMeetingItem)NewRedemptionObject(new Guid("FA2CBAFB-F7B1-4F41-9B7A-73329A6C1CB7")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafePostItem new_SafePostItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafePostItem)NewRedemptionObject(new Guid("11E2BC0C-5D4F-4E0C-B438-501FFE05A382")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeReportItem new_SafeReportItem() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeReportItem)NewRedemptionObject(new Guid("D46BA7B2-899F-4F60-85C7-4DF5713F6F18")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static MAPIFolder new_MAPIFolder() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (MAPIFolder)NewRedemptionObject(new Guid("03C4C5F4-1893-444C-B8D8-002F0034DA92")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeCurrentUser new_SafeCurrentUser() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeCurrentUser)NewRedemptionObject(new Guid("7ED1E9B1-CB57-4FA0-84E8-FAE653FE8E6B")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeDistList new_SafeDistList() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeDistList)NewRedemptionObject(new Guid("7C4A630A-DE98-4E3E-8093-E8F5E159BB72")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static AddressLists new_AddressLists() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (AddressLists)NewRedemptionObject(new Guid("37587889-FC28-4507-B6D3-8557305F7511")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static MAPITable new_MAPITable() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (MAPITable)NewRedemptionObject(new Guid("A6931B16-90FA-4D69-A49F-3ABFA2C04060")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static MAPIUtils new_MAPIUtils() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (MAPIUtils)NewRedemptionObject(new Guid("4A5E947E-C407-4DCC-A0B5-5658E457153B")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeInspector new_SafeInspector() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeInspector)NewRedemptionObject(new Guid("ED323630-B4FD-4628-BC6A-D4CC44AE3F00")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        public static SafeExplorer new_SafeExplorer() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            return (SafeExplorer)NewRedemptionObject(new Guid("C3B05695-AE2C-4FD5-A191-2E4C782C03E0")); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        #endregion `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        #region private methods `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        static RedemptionLoader() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            //default locations of the dlls `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`            //use CodeBase instead of Location because of Shadow Copy. `:@LF
  cSharpSource = cSharpSource :`            string codebase = Assembly.GetExecutingAssembly().CodeBase; `:@LF
  cSharpSource = cSharpSource :`            var vUri = new UriBuilder(codebase); `:@LF
  cSharpSource = cSharpSource :`            string vPath = Uri.UnescapeDataString(vUri.Path + vUri.Fragment); `:@LF
  cSharpSource = cSharpSource :`            string directory = Path.GetDirectoryName(vPath); `:@LF
  cSharpSource = cSharpSource :`            if (!string.IsNullOrEmpty(vUri.Host)) directory = @"\\" + vUri.Host + directory; `:@LF
  cSharpSource = cSharpSource :`            DllLocation64Bit = Path.Combine(directory, "redemption64.dll"); `:@LF
  cSharpSource = cSharpSource :`            DllLocation32Bit = Path.Combine(directory, "redemption.dll"); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        /* `:@LF
  cSharpSource = cSharpSource :`        static ~Loader() `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            if (!_redemptionDllHandle.Equals(IntPtr.Zero)) `:@LF
  cSharpSource = cSharpSource :`            { `:@LF
  cSharpSource = cSharpSource :`                IntPtr dllCanUnloadNowPtr = Win32NativeMethods.GetProcAddress(_redemptionDllHandle, "DllCanUnloadNow"); `:@LF
  cSharpSource = cSharpSource :`                if (!dllCanUnloadNowPtr.Equals(IntPtr.Zero)) `:@LF
  cSharpSource = cSharpSource :`                { `:@LF
  cSharpSource = cSharpSource :`                    DllCanUnloadNow dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(dllCanUnloadNowPtr, typeof(DllCanUnloadNow)); `:@LF
  cSharpSource = cSharpSource :`                    if (dllCanUnloadNow() != 0) return; //there are still live objects returned by the dll, so we should not unload the dll `:@LF
  cSharpSource = cSharpSource :`                } `:@LF
  cSharpSource = cSharpSource :`                Win32NativeMethods.FreeLibrary(_redemptionDllHandle); `:@LF
  cSharpSource = cSharpSource :`                _redemptionDllHandle = IntPtr.Zero; `:@LF
  cSharpSource = cSharpSource :`            } `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :`        */ `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        [ComVisible(false)] `:@LF
  cSharpSource = cSharpSource :`        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000001-0000-0000-C000-000000000046")] `:@LF
  cSharpSource = cSharpSource :`        private interface IClassFactory `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            void CreateInstance([MarshalAs(UnmanagedType.Interface)] object pUnkOuter, ref Guid refiid, [MarshalAs(UnmanagedType.Interface)] out object ppunk); `:@LF
  cSharpSource = cSharpSource :`            void LockServer(bool fLock); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        [ComVisible(false)] `:@LF
  cSharpSource = cSharpSource :`        [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000000-0000-0000-C000-000000000046")] `:@LF
  cSharpSource = cSharpSource :`        private interface IUnknown `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        private delegate int DllGetClassObject(ref Guid ClassId, ref Guid InterfaceId, [Out, MarshalAs(UnmanagedType.Interface)] out object ppunk); `:@LF
  cSharpSource = cSharpSource :`        private delegate int DllCanUnloadNow(); `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        //COM GUIDs `:@LF
  cSharpSource = cSharpSource :`        private static Guid IID_IClassFactory = new Guid("00000001-0000-0000-C000-000000000046"); `:@LF
  cSharpSource = cSharpSource :`        private static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        //win32 functions to load\unload dlls and get a function pointer  `:@LF
  cSharpSource = cSharpSource :`        private class Win32NativeMethods `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] `:@LF
  cSharpSource = cSharpSource :`            public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`            [DllImport("kernel32.dll", SetLastError = true)] `:@LF
  cSharpSource = cSharpSource :`            public static extern bool FreeLibrary(IntPtr hModule); `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`            [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] `:@LF
  cSharpSource = cSharpSource :`            public static extern IntPtr LoadLibraryW(string lpFileName); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        //private variables `:@LF
  cSharpSource = cSharpSource :`        private static IntPtr _redemptionDllHandle = IntPtr.Zero; `:@LF
  cSharpSource = cSharpSource :`        private static IntPtr _dllGetClassObjectPtr = IntPtr.Zero; `:@LF
  cSharpSource = cSharpSource :`        private static DllGetClassObject _dllGetClassObject; `:@LF
  cSharpSource = cSharpSource :`        private static readonly object _criticalSection = new object(); `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        private static IUnknown NewRedemptionObject(Guid guid) `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            //try to set the thread COM apartment `:@LF
  cSharpSource = cSharpSource :`            //Thread.CurrentThread.ApartmentState = ApartmentState.STA; `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`            object res = null; `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`            lock (_criticalSection) `:@LF
  cSharpSource = cSharpSource :`            { `:@LF
  cSharpSource = cSharpSource :`                IClassFactory ClassFactory; `:@LF
  cSharpSource = cSharpSource :`                if (_redemptionDllHandle.Equals(IntPtr.Zero)) `:@LF
  cSharpSource = cSharpSource :`                { `:@LF
  cSharpSource = cSharpSource :`                    string dllPath; `:@LF
  cSharpSource = cSharpSource :`                    if (IntPtr.Size == 8) dllPath = DllLocation64Bit; `:@LF
  cSharpSource = cSharpSource :`                    else dllPath = DllLocation32Bit; `:@LF
  cSharpSource = cSharpSource :`                    _redemptionDllHandle = Win32NativeMethods.LoadLibraryW(dllPath); `:@LF
  cSharpSource = cSharpSource :`                    if (_redemptionDllHandle.Equals(IntPtr.Zero)) `:@LF
  cSharpSource = cSharpSource :`                        //throw new Exception(string.Format("Could not load '{0}'\nMake sure the dll exists.", dllPath)); `:@LF
  cSharpSource = cSharpSource :`                        throw new Win32Exception(Marshal.GetLastWin32Error()); `:@LF
  cSharpSource = cSharpSource :`                    _dllGetClassObjectPtr = Win32NativeMethods.GetProcAddress(_redemptionDllHandle, "DllGetClassObject"); `:@LF
  cSharpSource = cSharpSource :`                    if (_dllGetClassObjectPtr.Equals(IntPtr.Zero)) `:@LF
  cSharpSource = cSharpSource :`                        //throw new Exception("Could not retrieve a pointer to the 'DllGetClassObject' function exported by the dll"); `:@LF
  cSharpSource = cSharpSource :`                        throw new Win32Exception(Marshal.GetLastWin32Error()); `:@LF
  cSharpSource = cSharpSource :`                    _dllGetClassObject = `:@LF
  cSharpSource = cSharpSource :`                        (DllGetClassObject) `:@LF
  cSharpSource = cSharpSource :`                        Marshal.GetDelegateForFunctionPointer(_dllGetClassObjectPtr, typeof(DllGetClassObject)); `:@LF
  cSharpSource = cSharpSource :`                } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`                Object unk; `:@LF
  cSharpSource = cSharpSource :`                int hr = _dllGetClassObject(ref guid, ref IID_IClassFactory, out unk); `:@LF
  cSharpSource = cSharpSource :`                if (hr != 0) throw new Exception("DllGetClassObject failed with error code 0x" + hr.ToString("x8")); `:@LF
  cSharpSource = cSharpSource :`                ClassFactory = unk as IClassFactory; `:@LF
  cSharpSource = cSharpSource :`                ClassFactory.CreateInstance(null, ref IID_IUnknown, out res); `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`                //If the same class factory is returned as the one still `:@LF
  cSharpSource = cSharpSource :`                //referenced by .Net, the call will be marshalled to the original thread `:@LF
  cSharpSource = cSharpSource :`                //where that class factory was retrieved first. `:@LF
  cSharpSource = cSharpSource :`                //Make .Net forget these objects `:@LF
  cSharpSource = cSharpSource :`                Marshal.ReleaseComObject(unk); `:@LF
  cSharpSource = cSharpSource :`                Marshal.ReleaseComObject(ClassFactory); `:@LF
  cSharpSource = cSharpSource :`            } //lock `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`            return (res as IUnknown); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`        #endregion `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`    } `:@LF
  cSharpSource = cSharpSource :` `:@LF
  cSharpSource = cSharpSource :`    /* `:@LF
  cSharpSource = cSharpSource :`    public class RDOSession : RDOSessionClass  `:@LF
  cSharpSource = cSharpSource :`    { `:@LF
  cSharpSource = cSharpSource :`        static RDOSession()
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            ExtensibleClassFactory.RegisterObjectCreationCallback(callbackCreate_RDOSession); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :`        static private IntPtr callbackCreate_RDOSession(IntPtr aggregator) `:@LF
  cSharpSource = cSharpSource :`        { `:@LF
  cSharpSource = cSharpSource :`            object o = RedemptionLoader.new_RDOSession(); `:@LF
  cSharpSource = cSharpSource :`            return Marshal.GetIUnknownForObject(o); `:@LF
  cSharpSource = cSharpSource :`        } `:@LF
  cSharpSource = cSharpSource :`    } `:@LF
  cSharpSource = cSharpSource :`    */ `:@LF
  cSharpSource = cSharpSource :`} `:@LF







  objResult = objCSharp.CompileAssemblyFromSource(objParams,cSharpSource)

  ;Compiler Output
  If objResult.Output.Count > 0 Then
    strOutput = ''
    For x = 0 to objResult.Output.Count-1
       If strOutput == "" Then
         strOutput = objResult.Output.Item(x)
       Else
         strOutput = strOutput:@LF:objResult.Output.Item(x)
       EndIf
    Next
    Pause('Compiler Output',strOutput)
  Endif
 
  ; Compiler Errors
  If objResult.Errors.Count > 0 Then
    strErrors = ''
    ForEach ce In objResult.Errors
      ;Pause("Error", ce.ToString())
      If strErrors == "" Then
        strErrors = ce.ToString()
      Else
        strErrors = strErrors:@LF:ce.ToString()
      EndIf
    Next
    Pause('Compiler Errors',strErrors)
    Exit
  EndIf
 


#EndSubRoutine


Return