WebMasterSam

.Net, SEO, Dynamics CRM, AdSense/AdWords, Dating sites, Silverlight, Web hosting and more
PPC management, Online Marketing, Search Marketing, SEO, Website development - dotmedias.com

About me

I'm an IT consultant working primarily with the .Net Framework as a developper and architect. I also work on my own on my personnal dating websites. I've been developping websites since 2000.

If you like what I do, feel free to support me

PayPal - The safer, easier way to pay online!

Bookmark

Bookmark and Share

Sponsored links

Amazon hot deals

Computer releases

Last comments

None

Complete .Net COM+ interop class (COMAdmin wrapper)

If you already worked with the Interop.COMAdmin, you certainly said a lot of bad bad words ! Don't worry, you're not alone. Recently a friend of mine has to create an application that can export security from COM+ and then reimport it on another server. Because I love to do very technical code I decided to write a complete COM+ interop class that wraps the Interop.COMAdmin one. By doing this, my friend had a clean interop do deal with and so the tool to export security has been realized very quickly.

I decided to write a really clean interop so I spent about 3 days of work just to write this interop because no one on the internet has took the time to create it ! I want to share it with you because it can make you save a looooooooooot of time and frustration. You can download the code right here : ComPlusInterop.zip (31.45 kb).

The architecture behind that interop is as follow; there is a base class, COMElementBase, that wraps the access to the COMObject and there is derived classes matching the different things in COM+ such a applications, components, roles, methods and interfaces. Here is a list of the different classes the interop has :

  • ComponentServices
    • Represents the COM+ instance (can be from a remote server)
  • COMElementBase
    • The base class for the following classes
  • COMApplication
    • Represents an application
  • COMComponent
    • Represents a component (DLL)
  • COMInterface
    • Represents an interface of a component
  • COMMethod
    • Represents a method of an interface
  • COMRole
    • Represents a role definition
Because everything in COM+ is retrieved by string, I have a lot of constant values in each different class; each constant matches the internal property name. To retrieve a property value or to set one, the derived class (such as COMApplication) calls an internal method of the COMElementBase class. To simplify the process of casting property values, I created several methods in the base class to retrieve property values like GetPropertyValueBoolean, GetPropertyValueInteger and so on...

To show you in code what it looks like, here's the COMComponent class :


using Interop.COMAdmin;

using System.Runtime.InteropServices;

public class COMComponent : COMElementBase, IComparable
{
    #region "Members"

        private ReadOnlyCollection<COMInterface> _lstInterfaces;
        private ReadOnlyCollection<string> _lstRoles;
        private COMApplication _parent = null;

        private COMAdminCatalogCollection _colInterfaces = null;
        private COMAdminCatalogCollection _colRoles = null;

        private bool _dispose = false;

    #endregion

    #region "Constantss"

        internal const string NUMBER_ERROR_VERSION_INVALID = "0x8011042C";

        internal const string KEY_COLLECTION_INTERFACE = "InterfacesForComponent";
        internal const string KEY_COLLECTION_ROLES = "RolesForComponent";

        internal const string PROPERTY_NAME = "ProgID";
        internal const string PROPERTY_GUID = "CLSID";
        internal const string PROPERTY_DESCRIPTION = "Description";
        internal const string PROPERTY_DLL = "DLL";
        internal const string PROPERTY_MAJOR_VERSION = "VersionMajor";
        internal const string PROPERTY_MINOR_VERSION = "VersionMinor";
        internal const string PROPERTY_BUILD_VERSION = "VersionBuild";
        internal const string PROPERTY_SUBBUILD_VERSION = "VersionSubBuild";
        internal const string PROPERTY_TRANSACTION = "Transaction";
        internal const string PROPERTY_COMPONENT_TRANSACTION_TIMEOUT_ENABLED = "ComponentTransactionTimeoutEnabled";
        internal const string PROPERTY_COMPONENT_TRANSACTION_TIMEOUT = "ComponentTransactionTimeout";
        internal const string PROPERTY_ACCESS_CHECKS_ENABLED = "ComponentAccessChecksEnabled";
        internal const string PROPERTY_POOLING_ENABLED = "ObjectPoolingEnabled";
        internal const string PROPERTY_MAX_POOL_SIZE = "MaxPoolSize";
        internal const string PROPERTY_MIN_POOL_SIZE = "MinPoolSize";
        internal const string PROPERTY_CREATION_TIMEOUT = "CreationTimeout";
        internal const string PROPERTY_CONSTRUCTION_ENABLED = "ConstructionEnabled";
        internal const string PROPERTY_CONSTRUCTION_STRING = "ConstructorString";
        internal const string PROPERTY_JIT_ACTIVATION = "JustInTimeActivation";
        internal const string PROPERTY_EVENT_TRACKING_ENABLED = "EventTrackingEnabled";
        internal const string PROPERTY_MUST_RUN_IN_CLIENT_CONTEXT = "MustRunInClientContext";
        internal const string PROPERTY_MUST_RUN_IN_DEFAULT_CONTEXT = "MustRunInDefaultContext";
        internal const string PROPERTY_IS_PRIVATE = "IsPrivateComponent";
        internal const string PROPERTY_SYNCHRONIZATION = "Synchronization";
        internal const string PROPERTY_THREADING_MODEL = "ThreadingModel";
        internal const string PROPERTY_EXCEPTION_CLASS = "ExceptionClass";

    #endregion

    #region "CTOR"

        internal COMComponent(COMAdminCatalogObject COMobject, COMAdminCatalogCollection collection, COMApplication parent)
            : base(COMobject, collection)
        {


            _parent = parent;
        }

        protected override void Dispose(bool disposing)
        {

            base.Dispose(disposing);

            if (!_dispose)
            {

                if (_colInterfaces != null)
                {
                    Marshal.ReleaseComObject(_colInterfaces);
                }

                if (_colRoles != null)
                {
                    Marshal.ReleaseComObject(_colRoles);

                }
            }


            _dispose = true;
        }

    #endregion

    #region "Properties"

        public ReadOnlyCollection<COMInterface> Interfaces
        {
            get
            {

                if (_lstInterfaces == null)
                {
                    RetrieveInterfaces();
                }


                return _lstInterfaces;
            }
        }

        public ReadOnlyCollection<string> RolesCoches
        {
            get
            {

                if (_lstRoles == null)
                {
                    RetrieveRoles();
                }


                return _lstRoles;
            }
        }

        public string Name
        {
            get { return base.GetPropertyValueString(PROPERTY_NAME); }
        }

        public Guid ID
        {
            get { return base.GetPropertyValueGUID(PROPERTY_GUID); }
        }

        public string DLLPath
        {
            get { return base.GetPropertyValueString(PROPERTY_DLL); }
        }

        public string Version
        {
            get { return string.Format("{0}.{1}.{2}.{3}", base.GetPropertyValueInteger(PROPERTY_MAJOR_VERSION), base.GetPropertyValueInteger(PROPERTY_MINOR_VERSION), base.GetPropertyValueInteger(PROPERTY_BUILD_VERSION), base.GetPropertyValueInteger(PROPERTY_SUBBUILD_VERSION)); }
        }

        public string Description
        {
            get { return base.GetPropertyValueString(PROPERTY_DESCRIPTION); }
            set { base.SetPropertyValue(PROPERTY_DESCRIPTION, value); }
        }
        public bool ComponentTransactionTimeoutEnabled
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_COMPONENT_TRANSACTION_TIMEOUT_ENABLED); }
            set { base.SetPropertyValue(PROPERTY_COMPONENT_TRANSACTION_TIMEOUT_ENABLED, value); }
        }

        public int ComponentTransactionTimeout
        {
            get { return base.GetPropertyValueInteger(PROPERTY_COMPONENT_TRANSACTION_TIMEOUT); }
            set
            {
                if (value < 0 || value > 3600)
                {
                    throw new OverflowException("La valeur doit être comprise entre 0 et 3600.");
                }
                else
                {
                    base.SetPropertyValue(PROPERTY_COMPONENT_TRANSACTION_TIMEOUT, value);
                }
            }
        }

        public bool AccessChecksEnabled
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_ACCESS_CHECKS_ENABLED); }
            set { base.SetPropertyValue(PROPERTY_ACCESS_CHECKS_ENABLED, value); }
        }

        public bool PoolingEnabled
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_POOLING_ENABLED); }
            set { base.SetPropertyValue(PROPERTY_POOLING_ENABLED, value); }
        }

        public int MaxPoolSize
        {
            get { return base.GetPropertyValueInteger(PROPERTY_MAX_POOL_SIZE); }
            set
            {
                if (value < 1 || value > 1048576)
                {
                    throw new OverflowException("The value must be between 1 and 1048576.");
                }
                else
                {
                    base.SetPropertyValue(PROPERTY_MAX_POOL_SIZE, value);
                }
            }
        }

        public int MinPoolSize
        {
            get { return base.GetPropertyValueInteger(PROPERTY_MIN_POOL_SIZE); }
            set
            {
                if (value < 0 || value > 1048576)
                {
                    throw new OverflowException("The value must be between 0 and 1048576.");
                }
                else
                {
                    base.SetPropertyValue(PROPERTY_MIN_POOL_SIZE, value);
                }
            }
        }

        public int CreationTimeout
        {
            get { return base.GetPropertyValueInteger(PROPERTY_CREATION_TIMEOUT); }
            set
            {
                if (value < 0 || value > 2147483647)
                {
                    throw new OverflowException("The value must be between 0 and 2147483647.");
                }
                else
                {
                    base.SetPropertyValue(PROPERTY_CREATION_TIMEOUT, value);
                }
            }
        }

        public bool ConstructionEnabled
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_CONSTRUCTION_ENABLED); }
            set { base.SetPropertyValue(PROPERTY_CONSTRUCTION_ENABLED, value); }
        }

        public string ConstructionString
        {
            get { return base.GetPropertyValueString(PROPERTY_CONSTRUCTION_STRING); }
            set { base.SetPropertyValue(PROPERTY_CONSTRUCTION_STRING, value); }
        }

        public bool JITActivation
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_JIT_ACTIVATION); }
            set { base.SetPropertyValue(PROPERTY_JIT_ACTIVATION, value); }
        }

        public bool EventTrackingEnabled
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_EVENT_TRACKING_ENABLED); }
            set { base.SetPropertyValue(PROPERTY_EVENT_TRACKING_ENABLED, value); }
        }

        public bool MustRunInClientContext
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_MUST_RUN_IN_CLIENT_CONTEXT); }
            set { base.SetPropertyValue(PROPERTY_MUST_RUN_IN_CLIENT_CONTEXT, value); }
        }

        public bool MustRunInDefaultContext
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_MUST_RUN_IN_DEFAULT_CONTEXT); }
            set { base.SetPropertyValue(PROPERTY_MUST_RUN_IN_DEFAULT_CONTEXT, value); }
        }

        public bool IsPrivate
        {
            get { return base.GetPropertyValueBoolean(PROPERTY_IS_PRIVATE); }
            set { base.SetPropertyValue(PROPERTY_IS_PRIVATE, value); }
        }

    #endregion

    #region "Public methods"

        public void AssociateRole(string name)
        {

            if (_colRoles == null)
            {
                RetrieveRoles();
            }

            if (!_colRoles.AddEnabled)
            {
                throw new NotSupportedException("Associating role is not supported.");
            }

            if (this.Parent.IsSystem)
            {
                throw new NotSupportedException("Cannot associate role in a system application.");
            }

            if (!this.Parent.Changeable)
            {
                throw new NotSupportedException("The application does not support modifications.");
            }

            if (RoleAssociated(name))
            {
                throw new DuplicateNameException(string.Format("The role '{0}' is already associated with this component.", name));
            }

            COMAdminCatalogObject role = (COMAdminCatalogObject)_colRoles.Add();

            role.Value(COMRole.PROPERTY_NAME) = (object)name;

            _colRoles.SaveChanges();


            RetrieveRoles();
        }

        public void DissociateRole(string name)
        {

            if (_colRoles == null)
            {
                RetrieveRoles();
            }

            if (!_colRoles.AddEnabled)
            {
                throw new NotSupportedException("Dissociating role is not supported.");
            }

            if (this.Parent.IsSystem)
            {
                throw new NotSupportedException("Cannot dissociate role in a system application.");
            }

            if (!this.Parent.Changeable)
            {
                throw new NotSupportedException("The application does not support modifications.");
            }

            if (!RoleAssociated(name))
            {
                throw new KeyNotFoundException(string.Format("The role '{0}' is not associated with this component.", name));
            }

            for (int i = 0; i <= _colRoles.Count - 1; i++)
            {
                if (((string)((COMAdminCatalogObject)_colRoles.Item(i)).Name).ToLower() == name.ToLower())
                {
                    _colRoles.Remove(i);
                    break;
                }
            }

            _colRoles.SaveChanges();

            RetrieveRoles();
        }

        public void DissociateRoles()
        {

            for (int i = this.RolesCoches.Count - 1; i >= 0; i += -1)
            {
                DissociateRole(this.RolesCoches(i));

            }
        }

        public bool RoleAssociated(string name)
        {

            bool found = false;

            for (int i = 0; i <= this.RolesCoches.Count - 1; i++)
            {
                if (this.RolesCoches(i).ToLower() == name.ToLower())
                {
                    found = true;
                    break;
                }
            }


            return found;
        }

        public bool InterfaceExists(string name)
        {

            bool found = false;

            for (int i = 0; i <= this.Interfaces.Count - 1; i++)
            {
                if (this.Interfaces(i).Name.ToLower() == name.ToLower())
                {
                    found = true;
                    break;
                }
            }


            return found;
        }

        public COMInterface RetrieveInterface(string name)
        {

            COMInterface interfaceFound = null;

            for (int i = 0; i <= this.Interfaces.Count - 1; i++)
            {
                if (this.Interfaces(i).Name.ToLower() == name.ToLower())
                {
                    interfaceFound = this.Interfaces(i);
                    break;
                }
            }

            if (interfaceFound == null)
            {
                throw new KeyNotFoundException(string.Format("The interface '{0}' was not found.", name));
            }


            return interfaceFound;
        }

        public void Refresh()
        {

            RetrieveInterfaces();

            RetrieveRoles();
        }

        public int CompareTo(object obj)
    {


        return this.Name.CompareTo(((COMComponent)obj).Name);
    }

    #endregion

    #region "Private methods"

        private void RetrieveInterfaces()
        {

            _lstInterfaces = new ReadOnlyCollection<COMInterface>();

            _colInterfaces = base.GetCollection(KEY_COLLECTION_INTERFACE);

            for (int i = 0; i <= _colInterfaces.Count - 1; i++)
            {
                _lstInterfaces.Add(new COMInterface((COMAdminCatalogObject)_colInterfaces.Item(i), _colInterfaces, this));
            }


            _lstInterfaces.Sort();
        }

        private void RetrieveRoles()
    {

        _lstRoles = new ReadOnlyCollection<string>();

        _colRoles = base.GetCollection(KEY_COLLECTION_ROLES);

        for (int i = 0; i <= _colRoles.Count - 1; i++)
        {
            _lstRoles.Add((string)((COMAdminCatalogObject)_colRoles.Item(i)).Name);
        }


        _lstRoles.Sort();
    }

    #endregion
}

Once again, if you want to download the code, you can get it here : ComPlusInterop.zip (31.45 kb).
If you want a complete COM+ programming reference, you can check this MSDN article. This is where I got all the string needed to retrieve property values from COMAdmin.
Enjoy !
LINK BUILDING IS PROHIBITED ON THIS WEBSITE