Currently mfreg is used to point to a specific Presentation server in a farm from the client machine. All the MFCOM calls get routed to that specific machine and talk to MFCOM running on that Presentation Server. This technique uses DCOM client machine defaults when it gets new MFCOM interfaces on that machine.

The main drawback with the above method is that it always points to only one server in the farm and you could potentially manage only one farm. What if you want to manage more than one farm by talking to more than one server in the same program? You can achieve this programmatically instead of using mfreg.

Basically it involves using the “servername” of the Presentation Server where MFCOM is running while creating objects and interfaces. We will look at how this could be achieved in C# and VBScript.

In C# :
These simple function in C# creates an interface of Type T on a server named “serverName”.

object GetComObjectForServer<T>(string serverName)
{
try
{
Guid guid = typeof(T).GUID;
Type t = Type.GetTypeFromCLSID(guid, serverName, true);
return Activator.CreateInstance(t);
}
catch (Exception ex)
{
Trace.WriteLine(ex);
return default(T);
}
}

Once interface is created, then client security for that interface needs to be set. Pass in the above object to the method below to set the Client Security. Then you can use the interface and access its methods and properties.

void SetClientSecurity<T>(T obj)
{
if (obj == null)
throw new ArgumentNullException(“obj”);

IntPtr ptr = Marshal.GetComInterfaceForObject(obj, typeof(T));

if (ptr == IntPtr.Zero)
throw new ArgumentException(“can’t get COM interface for object”, “obj”);

int result = NativeMethods.CoSetProxyBlanket(
ptr,
10 /* RPC_C_AUTHN_WINNT */,
0 /* RPC_C_AUTHZ_NONE */,
pServerPrincName,
6 /* RPC_C_AUTHN_LEVEL_PKT_PRIVACY */,
3 /* RPC_C_IMP_LEVEL_IMPERSONATE */,
IntPtr.Zero,
0 /* NONE */);

Marshal.Release(ptr);
if (result < 0)
Marshal.ThrowExceptionForHR(result)
}

private class NativeMethods
{
private NativeMethods() { }
[DllImport(“ole32.dll”, PreserveSig = true, SetLastError = false)]

public static extern int CoSetProxyBlanket(
IntPtr pProxy,
int dwAuthnSvc,
int dwAuthzSvc,
IntPtr pServerPrincName,
int pAuthnLevel,
int pImpLevel,
IntPtr pAuthInfo,
int capabilities);
}


In VBScript (WSH):

To create an object on the remote machine in WSH just use the ServerName in CreateObject.

Set theFarm1 = CreateObject(“MetaFrameCOM.MetaFrameFarm”, ServerName1)
Set theServer1 = CreateObject(“MetaFrameCOM.MetaFrameServer”, ServerName1)

Set theFarm2 = CreateObject(“MetaFrameCOM.MetaFrameFarm”, ServerName2)
Set theServer2 = CreateObject(“MetaFrameCOM.MetaFrameServer”, ServerName2)

If ServerName1 and ServerName2 CPS Servers belong to two different Farms, then you have theFarm1 and theServer1 pointing to Farm1 and theFarm2 and theServer2 Objects pointing to Farm2.

These above mentioned techniques will help you to create MFCOM objects and interfaces on any CPS Server without restricting yourself to one CPS Server in a program pointed by mfreg. You still need to run mfreg to resgiter MFCOM on the client machine but you could either just register locally or even preferred CPS Server. The above mentioned methods ignore the server pointed by mfreg.