/// <summary>
 /// Creates default cursor type on category with default options.
 /// </summary>
 /// <param name="cmc">Native FormOA (Commence) reference.</param>
 /// <param name="pName">Commence category name.</param>
 /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 internal CommenceCursor(FormOA.ICommenceDB cmc, string pName, IRcwReleasePublisher rcwReleasePublisher)
 {
     // default cursor type, on category, default flag
     _cur = cmc.GetCursor(0, pName, 0);
     _rcwReleasePublisher             = rcwReleasePublisher;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
 /// <summary>
 /// Creates custom Category cursor.
 /// </summary>
 /// <param name="cmc">Native FormOA (Commence) reference.</param>
 /// <param name="pCursorType">CmcCursorType.</param>
 /// <param name="pName">Commence category or view name.</param>
 /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 /// <param name="pCursorFlags">CmcOptionFlags.</param>
 internal CommenceCursor(FormOA.ICommenceDB cmc, CmcCursorType pCursorType, string pName, IRcwReleasePublisher rcwReleasePublisher, CmcOptionFlags pCursorFlags)
 {
     CursorType                       = pCursorType;
     Flags                            = pCursorFlags;
     _cur                             = cmc.GetCursor((int)pCursorType, pName, (int)pCursorFlags); // notice the type conversion
     _rcwReleasePublisher             = rcwReleasePublisher;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
 /// <summary>
 /// Constructor that creates QueryRowSet with set number of items.
 /// </summary>
 /// <param name="cur">FormOA.ICommenceCursor reference.</param>
 /// <param name="nCount">Number of items to query.</param>
 /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 /// <param name="flags">option flags, must be 0.</param>
 internal CommenceQueryRowSet(FormOA.ICommenceCursor cur, int nCount, IRcwReleasePublisher rcwpub, CmcOptionFlags flags)
 {
     // queryrowset with set number of rows
     _qrs = cur.GetQueryRowSet(nCount, (int)flags);
     if (_qrs == null)
     {
         throw new CommenceCOMException("Unable to obtain a QueryRowSet from Commence.");
     }
     _rcwReleasePublisher             = rcwpub;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
 /// <summary>
 /// Constructor that creates EditRowSet for particular row identified by RowID.
 /// </summary>
 /// <param name="cur">FormOA.ICommenceCursor reference.</param>
 /// <param name="pRowID">row id.</param>
 /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 /// <param name="flags">option flags, must be 0.</param>
 internal CommenceEditRowSet(FormOA.ICommenceCursor cur, string pRowID, IRcwReleasePublisher rcwpub, CmcOptionFlags flags)
 {
     // editrowset by ID
     _ers = cur.GetEditRowSetByID(pRowID, (int)flags);
     if (_ers == null)
     {
         throw new CommenceCOMException("Unable to obtain a EditRowSet from Commence.");
     }
     _rcwReleasePublisher             = rcwpub;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
Exemple #5
0
 /// <summary>
 /// Constructor that creates DeleteRowSet with all items.
 /// </summary>
 /// <param name="cur">FormOA.ICommenceCursor reference.</param>
 /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 /// <param name="flags">Option flags, must be 0.</param>
 internal CommenceDeleteRowSet(FormOA.ICommenceCursor cur, IRcwReleasePublisher rcwpub, CmcOptionFlags flags)
 {
     // deleterowset with all rows
     _drs = cur.GetDeleteRowSet(cur.RowCount, (int)flags);
     if (_drs == null)
     {
         throw new CommenceCOMException("Unable to obtain a DeleteRowSet from Commence.");
     }
     _rcwReleasePublisher             = rcwpub;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
 /// <summary>
 /// Creates custom View cursor.
 /// </summary>
 /// <param name="cmc">Native FormOA (Commence) reference.</param>
 /// <param name="pCursorType">CmcCursorType.</param>
 /// <param name="pName">Commence category or view name.</param>
 /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 /// <param name="pCursorFlags">CmcOptionFlags.</param>
 /// <param name="viewType">Viewtype.</param>
 internal CommenceCursor(FormOA.ICommenceDB cmc, CmcCursorType pCursorType, string pName, IRcwReleasePublisher rcwReleasePublisher, CmcOptionFlags pCursorFlags, string viewType)
 {
     CursorType = pCursorType;
     Flags      = pCursorFlags;
     if (CursorType == CmcCursorType.View)
     {
         _viewName = pName;
         //_viewType = Utils.GetValueFromEnumDescription<CommenceViewType>(viewType);
         _viewType = Utils.EnumFromAttributeValue <CommenceViewType, StringValueAttribute>(nameof(StringValueAttribute.StringValue), viewType);
     }
     _cur = cmc.GetCursor((int)pCursorType, pName, (int)pCursorFlags); // notice the type conversion
     _rcwReleasePublisher             = rcwReleasePublisher;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
Exemple #7
0
        /// <summary>
        /// Public constructor.
        /// </summary>
        public CommenceDatabase()
        {
            _app = new CommenceApp(); // when we call this first, the next line does not fail when called from COM.
            // we also want this call to CommenceApp because it contains the check to see if commence.exe is running.
            _db = _app.Db;

            /* We create a publisher object so any classes created from this instance can use it.
             * The idea is that this way, COM clients can create and close the several COM-visible components (CommenceApp, Export) safely.
             * It would be easier to use a static event notifying all classes that consume a COM resource to release it.
             * This leads to unwanted behaviour because all instances will be notified.
             * The down-side of the current approach is that we have to pass the event publisher to all classes that will subscribe to it.
             * There must be a better way?
             */
            _rcwReleasePublisher             = new RcwReleasePublisher();
            _rcwReleasePublisher.RCWRelease += _app.RCWReleaseHandler;
            _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
        }
 /// <summary>
 /// Constructor that creates QueryRowSet with all items.
 /// </summary>
 /// <param name="cur">FormOA.ICommenceCursor reference.</param>
 /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 /// <param name="flags">option flags, must be 0.</param>
 internal CommenceQueryRowSet(FormOA.ICommenceCursor cur, IRcwReleasePublisher rcwpub, CmcOptionFlags flags)
 {
     // queryrowset with all rows
     try
     {
         _qrs = cur.GetQueryRowSet(cur.RowCount, (int)flags);
     }
     catch (Exception)
     {
         // swallow all exceptions and throw our own.
     }
     if (_qrs == null)
     {
         throw new CommenceCOMException("Unable to obtain a QueryRowSet from Commence.");
     }
     _rcwReleasePublisher             = rcwpub;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }
        /// <summary>
        /// Constructor that creates QueryRowSet for particular row identified by RowID.
        /// </summary>
        /// <param name="cur">FormOA.ICommenceCursor reference.</param>
        /// <param name="pRowID">row or thid  id.</param>
        /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param>
        /// <param name="flags">option flags, must be 0.</param>
        /// <param name="identifier"><see cref="RowSetIdentifier"/></param>
        internal CommenceQueryRowSet(FormOA.ICommenceCursor cur, string pRowID, IRcwReleasePublisher rcwpub, CmcOptionFlags flags = CmcOptionFlags.Default, RowSetIdentifier identifier = RowSetIdentifier.RowId)
        {
            switch (identifier)
            {
            case RowSetIdentifier.RowId:
                _qrs = cur.GetQueryRowSetByID(pRowID, (int)flags);
                break;

            case RowSetIdentifier.Thid:
                // _qrs = cur.GetQueryRowSetByThid(pRowID, (int)flags);
                throw new NotSupportedException("GetQueryRowSetByThid no longer supported by Commence API");
                //break;
            }
            if (_qrs == null)
            {
                throw new CommenceCOMException("Unable to obtain a QueryRowSet from Commence.");
            }
            _rcwReleasePublisher             = rcwpub;
            _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
        }
        private FormOA.ICommenceDB _cmc; // The exposed root level name of Commence is 'FormOA' for reasons unknown to me

        #region Constructors

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <exception cref="CommenceNotRunningException">Commence is not running (COM error: 0x80131500).</exception>
        /// <exception cref="CommenceMultipleInstancesException">Commence is running more than 1 instance (COM error: 0x80131500).</exception>
        /// <remarks>If the constructor fails because either Commence is not running,
        /// or Commence is running multiple instances in the same userprofile, an exception is thrown.
        /// COM users (VBScript, VBA, etc.) will not get a useful error message.
        /// This is a bit of a problem that I am unsure how to solve.
        /// We could incorporate a lazy initialization routine and call that as soon as any of the properties are called,
        /// then return a more useful error to a consumer, but that is very messy from a .NET point of view.
        /// <para>Note that this behaviour may change in future releases.</para>
        /// <para>Note that if you want to execute a PowerShell of VBScript script, and Commence is started as administrator (or vice-versa),
        /// the script will prompt to start another instance of Commence. The userlevel of the user of the assembly must match the userlevel of the Commence instance.
        /// </para>
        /// </remarks>
        public CommenceApp()
        {
            /* Commence does not register itself in the ROT (Running Object Table)
             * Therefore, we can not tell which database to talk to from COM
             * This is a serious problem that Commence refuses to fix.
             * Most of the third-party utilities built for Commence do not take this into account,
             * they will happily try to talk to the first instance they encounter.
             * Calling CommenceDB when no commence.exe instance is running will fire up commence.exe and an arbitrary database, usually the last one opened.
             * This can be very much unwanted, especially in TS-like environments, so I tried to eliminate that possibility as much as possible
             * This assembly will simply not run if commence.exe is not running
             * The downside of this is that COM users will get an unintelligible error when no or multiple instances are running.
             * It will also not run if multiple commence.exe processes were started by the same user
             * It *should* run when different users started the commence.exe process
             * In that case, it *should* talk to the instance fired by the same user who calls the assembly
             * This behaviour may be subject to errors when Commence.DB has a non-standard DCOM settings defined.
             * This has yet to be tested.
             */
            rw             = new RcwReleasePublisher();
            rw.RCWRelease += RCWReleaseHandler;
        }
 /// <summary>
 /// Constructor that takes the raw FormOA.ICommenceCursor as parameter
 /// For use with the *RowSet CommitGetCursor methods
 /// </summary>
 /// <param name="cur">FormOA.ICommenceCursor.</param>
 /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param>
 internal CommenceCursor(FormOA.ICommenceCursor cur, IRcwReleasePublisher rcwReleasePublisher)
 {
     _cur = cur; // can be used with CommitGetCursor, or use SetCursor to re-use this object
     _rcwReleasePublisher             = rcwReleasePublisher;
     _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler;
 }