v2.9
How to access an existing Renga instance

Overview

You can access an already running Renga instance by means of the running object table (ROT). Each launched Renga instance has registered its own Application (IApplication interface) in the running object table (ROT) under the following monikers:

  • !Renga Application, ver: 2.6, pid: 1234
  • !{C94A380A-02F2-427B-8FD3-7D6572E16556}

The first one is human-readable. It contains information about the Renga API version and the process identifier. The second is the CLASS_ID for Renga Application.

Using either moniker, you can access and analyze running Renga instances of your choice.

You can also access a running Renga instance using the Marshal.GetActiveObject method. Calling this method with Renga Application programmatic identifier (ProgID) - "Renga.Application.1" as a parameter returns the first instance of Renga found if one exists.

When a client application releases a pointer to the IApplication, the Renga process continues execution.

Registration in the running object table (ROT) takes place regardless of whether Renga is started in the usual way or as a local server.

Running Object Table Example

Accessing a running Renga instance through the running object table (ROT).

C#

using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
...
[DllImport("ole32.dll")]
private static extern void GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
[DllImport("ole32.dll")]
private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc);
...
static public List<IMoniker> GetRengaMonikers()
{
IRunningObjectTable rot;
GetRunningObjectTable(0, out rot);
IEnumMoniker monikerEnumerator = null;
rot.EnumRunning(out monikerEnumerator);
if (monikerEnumerator == null)
return null;
monikerEnumerator.Reset();
var registries = new List<IMoniker>();
IntPtr pNumFetched = new IntPtr();
IMoniker[] monikers = new IMoniker[1];
while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0)
{
IBindCtx bindCtx;
CreateBindCtx(0, out bindCtx);
if (bindCtx == null)
continue;
string displayName;
monikers[0].GetDisplayName(bindCtx, null, out displayName);
if (displayName.Contains("!Renga"))
registries.Add(monikers[0]);
}
return registries;
}
...
IRunningObjectTable rot;
GetRunningObjectTable(0, out rot);
var rengaMonikers = GetRengaMonikers()
if (rengaMonikers.Count > 0)
{
object comObject;
// Get first Renga moniker in list
rot.GetObject(rengaMonikers[0], out comObject);
var renga = comObject as Renga.IApplication;
// Use Renga someway
}

Get Active Object Example

Accessing a running Renga instance using GetActiveObject.

C#

//Getting Renga by PROG_ID
renga = System.Runtime.InteropServices.Marshal.GetActiveObject("Renga.Application.1") as Renga.Application;
if (renga != null)
{
// Use first found Renga someway
// Release Renga
System.Runtime.InteropServices.Marshal.ReleaseComObject(renga);
}
else
{
// No running Renga instance
}

See also