|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.Tools.ServiceModel.ComSvcConfig
{
using System;
using System.ServiceModel.Channels;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Globalization;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using System.ServiceModel;
using System.EnterpriseServices;
using Microsoft.Tools.ServiceModel;
using Microsoft.Tools.ServiceModel.SvcUtil;
using Microsoft.Win32;
using System.Security.Permissions;
static internal partial class HR
{
public static readonly int COMADMIN_E_OBJECT_DOES_NOT_EXIST = unchecked((int)0x80110809);
}
enum RuntimeVersions
{
V20,
V40
}
static internal class ComAdminWrapper
{
static readonly string ListenerApplicationName = SR.GetString(SR.WebServiceAppName);
static Assembly ListenerAssembly = typeof(Message).Assembly;
static string ListenerComponentDescription = SR.GetString(SR.ListenerCompDescription);
const string ListenerWSUName = "ServiceModelInitializer";
internal const string Wcf30RegistryKey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v3.0\Setup\Windows Communication Foundation";
internal const string Runtime30InstallPathName = "RuntimeInstallPath";
const string fileName = @"ServiceMonikerSupport.dll";
static bool FindApplication(string appidOrName, out ICatalogObject targetAppObj, out ICatalogCollection appColl)
{
targetAppObj = null;
appColl = null;
bool found = false;
ICatalog2 catalog = GetCatalog();
string partitionId = null;
partitionId = GetPartitionIdForApplication(catalog, appidOrName, true);
if (!string.IsNullOrEmpty(partitionId))
{
SetCurrentPartition(catalog, partitionId);
}
appColl = (ICatalogCollection)(catalog.GetCollection(CollectionName.Applications));
appColl.Populate();
for (int i = 0; i < appColl.Count(); i++)
{
ICatalogObject appObj = (ICatalogObject)(appColl.Item(i));
string id = ((string)appObj.Key()).ToLowerInvariant();
string name = ((string)appObj.Name()).ToLowerInvariant();
appidOrName = appidOrName.ToLowerInvariant();
if (!found)
{
if ((appidOrName == id) || (appidOrName == name))
{
found = true;
targetAppObj = appObj;
}
}
else
{
if ((appidOrName == id) || (appidOrName == name))
{
throw Tool.CreateException(SR.GetString(SR.AmbiguousApplicationName, appidOrName), null);
}
}
}
return found;
}
static bool FindListener(Guid appid, out Guid clsid, out string progid)
{
clsid = Guid.Empty;
progid = null;
ICatalogObject appObj = null;
ICatalogCollection appColl = null;
if (!FindApplication(appid.ToString("B"), out appObj, out appColl))
{
throw Tool.CreateException(SR.GetString(SR.ApplicationNotFound, appid.ToString("B")), null);
}
ICatalogCollection comps = (ICatalogCollection)appColl.GetCollection(CollectionName.Components, appObj.Key());
comps.Populate();
for (int i = 0; i < comps.Count(); i++)
{
ICatalogObject compObj = (ICatalogObject)comps.Item(i);
if (IsListenerComponent(compObj))
{
clsid = new Guid((string)compObj.Key());
progid = (string)compObj.Name();
return true;
}
}
return false;
}
static bool SetComponentProperty(string appIdOrName, string compIdOrName, string property, object value)
{
ICatalogObject appObj = null;
ICatalogCollection appColl = null;
if (!FindApplication(appIdOrName, out appObj, out appColl))
{
throw Tool.CreateException(SR.GetString(SR.ApplicationNotFound, appIdOrName), null);
}
ICatalogCollection comps = (ICatalogCollection)appColl.GetCollection(CollectionName.Components, appObj.Key());
comps.Populate();
compIdOrName = compIdOrName.ToLowerInvariant(); //make compName lowercase
for (int i = 0; i < comps.Count(); i++)
{
ICatalogObject compObj = (ICatalogObject)comps.Item(i);
string name = ((string)compObj.Name()).ToLowerInvariant(); //make name lowercase
string id = ((string)compObj.Key()).ToLowerInvariant(); //make key lowercase
if (name == compIdOrName || id == compIdOrName)
{
compObj.SetValue(property, value);
comps.SaveChanges();
return true;
}
}
return false;
}
public static ComAdminAppInfo GetAppInfo(string appidOrName)
{
ICatalogObject appObj = null;
ICatalogCollection appColl = null;
if (!FindApplication(appidOrName, out appObj, out appColl))
{
return null;
}
ComAdminAppInfo appInfo = null;
try
{
appInfo = new ComAdminAppInfo(appObj, appColl);
}
catch (COMException ex)
{
ToolConsole.WriteWarning(SR.GetString(SR.FailedToFetchApplicationInformationFromCatalog, appidOrName, ex.ErrorCode, ex.Message));
}
return appInfo;
}
public static Guid[] GetApplicationIds()
{
ICatalog2 catalog = GetCatalog();
List<Guid> appIds = new List<Guid>();
ICatalogCollection partitions = (ICatalogCollection)(catalog.GetCollection(CollectionName.Partitions));
partitions.Populate();
for (int i = 0; i < partitions.Count(); i++)
{
ICatalogObject partition = (ICatalogObject)(partitions.Item(i));
ICatalogCollection applications = (ICatalogCollection)(partitions.GetCollection(CollectionName.Applications, partition.Key()));
applications.Populate();
for (int j = 0; j < applications.Count(); j++)
{
ICatalogObject obj = (ICatalogObject)(applications.Item(j));
appIds.Add(new Guid((string)obj.Key()));
}
}
return appIds.ToArray();
}
static ICatalog2 GetCatalog()
{
return (ICatalog2)(new xCatalog());
}
public static string GetPartitionIdForApplication(Guid appId)
{
ICatalog2 catalog = GetCatalog();
return GetPartitionIdForApplication(catalog, appId.ToString("B"), true);
}
public static string GetGlobalPartitionID()
{
ICatalog2 catalog = GetCatalog();
return catalog.GlobalPartitionID();
}
static string GetPartitionIdForApplication(ICatalog2 catalog, string appId, bool notThrow)
{
string partitionId = null;
try
{
partitionId = catalog.GetPartitionID(appId);
}
catch (COMException e)
{
if (!notThrow)
throw Tool.CreateException(SR.GetString(SR.CouldNotGetPartition), e);
else if (e.ErrorCode == HR.COMADMIN_E_OBJECT_DOES_NOT_EXIST)
ToolConsole.WriteWarning(SR.GetString(SR.ApplicationNotFound, appId));
else
ToolConsole.WriteWarning(SR.GetString(SR.CouldnotGetPartitionForApplication, appId, e.ErrorCode, e.Message));
return null;
}
return partitionId;
}
public static bool GetApplicationBitness(ICatalog2 catalog, string partitionID, string applicationID)
{
ICatalogCollection partitions = (ICatalogCollection)(catalog.GetCollection(CollectionName.Partitions));
ICatalogCollection applications = (ICatalogCollection)(partitions.GetCollection(CollectionName.Applications, partitionID));
applications.Populate();
ICatalogCollection components = (ICatalogCollection)applications.GetCollection(CollectionName.Components, applicationID);
try
{
components.Populate();
}
catch (Exception ex)
{
if (ex is NullReferenceException || ex is SEHException)
{
throw ex;
}
throw Tool.CreateException(SR.GetString(SR.FailedToDetermineTheBitnessOfApplication, applicationID), ex);
}
ICatalogObject component = (ICatalogObject)(components.Item(0));
return IsBitness64bit(component);
}
public static string GetAppropriateBitnessModuleModulePath(bool is64bit, RuntimeVersions runtimeVersion)
{
if (RuntimeVersions.V40 == runtimeVersion)
{
// Retrieve the regkey with Read permission. Note that on Windows 8 and later, only Trusted installer has write access to this key.
using (RegistryHandle regKey = RegistryHandle.GetCorrectBitnessHKLMSubkey(is64bit, ServiceModelInstallStrings.WinFXRegistryKey, false))
{
return (regKey.GetStringValue(ServiceModelInstallStrings.RuntimeInstallPathName).TrimEnd('\0') + "\\" + fileName);
}
}
else
{
// Try to find the 3.0 version
RegistryHandle regkey = null;
try
{
if (SafeNativeMethods.ERROR_SUCCESS == RegistryHandle.TryGetCorrectBitnessHKLMSubkey(is64bit, Wcf30RegistryKey, out regkey))
{
return (regkey.GetStringValue(Runtime30InstallPathName).TrimEnd('\0') + "\\" + fileName);
}
else
{
//We don't want to automatically roll forward to 4.0, so we throw an exception if we can't find the 3.0 reg key
throw Tool.CreateException(SR.GetString(SR.FailedToGetRegistryKey, Wcf30RegistryKey, "3.0"), null);
}
}
finally
{
if (regkey != null)
{
regkey.Dispose();
}
}
}
}
public static void CreateTypeLib(String fileName, Guid clsid)
{
try
{
ICreateTypeLib typelib = SafeNativeMethods.CreateTypeLib(fileName);
typelib.SetGuid(Guid.NewGuid());
typelib.SetName(ListenerWSUName);
typelib.SetDocString(ListenerWSUName);
ICreateTypeInfo typeInfo = typelib.CreateTypeInfo(ListenerWSUName, System.Runtime.InteropServices.ComTypes.TYPEKIND.TKIND_COCLASS);
typeInfo.SetGuid(clsid);
typeInfo.SetDocString(ListenerWSUName);
ICreateTypeInfo2 typeInfo2 = (ICreateTypeInfo2)typeInfo;
typeInfo2.SetName(ListenerWSUName + "Component");
typeInfo2.SetTypeFlags(2);
typeInfo.LayOut();
typelib.SaveAllChanges();
}
catch (Exception ex)
{
if (ex is NullReferenceException || ex is SEHException)
{
throw ex;
}
throw Tool.CreateException(SR.GetString(SR.FailedToCreateTypeLibrary), ex);
}
}
public static void CreateRegistryKey(bool is64bit, Guid clsid, string module)
{
using (RegistryHandle regKey = RegistryHandle.GetBitnessHKCR(is64bit))
{
using (RegistryHandle clsidKey = regKey.CreateSubKey(@"clsid\" + clsid.ToString("B")))
{
clsidKey.SetValue("", ListenerWSUName);
using (RegistryHandle inprocServer32Key = clsidKey.CreateSubKey("InprocServer32"))
{
inprocServer32Key.SetValue("", module);
inprocServer32Key.SetValue("ThreadingModel", "Both");
}
using (RegistryHandle progID = clsidKey.CreateSubKey("ProgID"))
{
progID.SetValue("", ListenerWSUName);
}
}
}
}
public static bool IsApplicationWow(Guid appid)
{
if (IntPtr.Size == 8)
{
string application = appid.ToString("B");
string partitionId = null;
ICatalog2 catalog = GetCatalog();
partitionId = GetPartitionIdForApplication(catalog, application, false);
// Search for the listener in this partition..
bool is64bit = GetApplicationBitness(catalog, partitionId, application);
return !is64bit;
}
else
return false;
}
public static void InstallListener(Guid appid, string path, RuntimeVersions runtimeVersion)
{
string application = appid.ToString("B");
string partitionId = null;
ICatalog2 catalog = GetCatalog();
partitionId = GetPartitionIdForApplication(catalog, application, false);
// Search for the listener in this partition..
bool is64bit = GetApplicationBitness(catalog, partitionId, application);
Guid clsidVal = Guid.NewGuid();
string clsid = clsidVal.ToString("B");
string tlb = Path.Combine(path, application + "." + clsid + ".tlb");
try
{
// No other listener in this partition, we're the first - install using RegistrationHelper
AtomicFile.SafeDeleteFile(tlb);
string modulePath = GetAppropriateBitnessModuleModulePath(is64bit, runtimeVersion);
if (string.IsNullOrEmpty(modulePath))
throw Tool.CreateException(SR.GetString(SR.CannotFindServiceInitializerModuleInRegistry), null);
CreateTypeLib(tlb, clsidVal);
CreateRegistryKey(is64bit, clsidVal, modulePath);
catalog.InstallComponent(application, modulePath, tlb, null);
MarkComponentAsPrivate(catalog, partitionId, application, ListenerWSUName);
if (!SetComponentProperty(application, ListenerWSUName, PropertyName.Description, ListenerComponentDescription))
ToolConsole.WriteWarning(SR.GetString(SR.CannotSetComponentDescription, clsid, appid.ToString("B")));
if (!SetComponentProperty(application, ListenerWSUName, PropertyName.InitializesServerApplication, "1"))
ToolConsole.WriteWarning(SR.GetString(SR.CannotSetComponentInitializerProperty, ListenerWSUName, appid.ToString("B")));
if (!SetComponentProperty(application, ListenerWSUName, PropertyName.ComponentAccessChecksEnabled, "0"))
ToolConsole.WriteWarning(SR.GetString(SR.CannotDisableAccessChecksOnInitializer, ListenerWSUName, appid.ToString("B")));
}
catch (Exception ex)
{
if (ex is NullReferenceException || ex is SEHException)
{
throw ex;
}
throw Tool.CreateException(SR.GetString(SR.CouldNotInstallListener), ex);
}
finally
{
AtomicFile.SafeDeleteFile(tlb);
}
}
static void MarkComponentAsPrivate(ICatalog2 catalog, string partitionID, string applicationID, string progid)
{
ICatalogCollection partitions = (ICatalogCollection)(catalog.GetCollection(CollectionName.Partitions));
ICatalogCollection applications = (ICatalogCollection)(partitions.GetCollection(CollectionName.Applications, partitionID));
applications.Populate();
ICatalogCollection components = (ICatalogCollection)applications.GetCollection(CollectionName.Components, applicationID);
try
{
components.Populate();
for (int j = 0; j < components.Count(); j++)
{
ICatalogObject component = (ICatalogObject)(components.Item(j));
if ((string)component.Name() == progid)
{
component.SetValue(PropertyName.IsPrivateComponent, true);
components.SaveChanges();
break;
}
}
}
catch (Exception ex)
{
if (ex is NullReferenceException || ex is SEHException)
{
throw ex;
}
ToolConsole.WriteWarning(SR.GetString(SR.FailedToMarkListenerComponentAsPrivateForApplication, progid, applicationID));
}
}
static bool IsBitness64bit(ICatalogObject component)
{
int bitness = (int)component.GetValue(PropertyName.Bitness);
if (bitness == 1)
{
return false;
}
else
{
return true;
}
}
internal static bool IsListenerComponent(ICatalogObject compObj)
{
string compName = (string)compObj.Name();
if (compName.ToUpperInvariant() == ListenerWSUName.ToUpperInvariant())
return true;
return false;
}
static void RemoveClsidFromRegistry(bool is64bit, string clsid)
{
RegistryHandle regKey = RegistryHandle.GetBitnessHKCR(is64bit);
string baseKey = "Clsid\\" + clsid;
regKey.DeleteKey(baseKey + "\\InprocServer32");
regKey.DeleteKey(baseKey + "\\ProgID");
regKey.DeleteKey(baseKey);
}
// returns true if deleted
static bool RemoveComponent(ICatalog2 catalog, string partitionId, string applicationId, string progid)
{
int deleteIndex = -1;
ICatalogCollection partitions = (ICatalogCollection)catalog.GetCollection(CollectionName.Partitions);
partitions.Populate();
ICatalogCollection applications = (ICatalogCollection)(partitions.GetCollection(CollectionName.Applications, partitionId));
applications.Populate();
ICatalogCollection components = (ICatalogCollection)(applications.GetCollection(CollectionName.Components, applicationId));
try
{
components.Populate();
bool is64bit = false;
string clsid = null;
for (int i = 0; i < components.Count(); i++)
{
ICatalogObject comp = (ICatalogObject)components.Item(i);
if (((string)comp.Name()).ToLowerInvariant() == progid.ToLowerInvariant())
{
clsid = ((string)comp.Key()).ToLowerInvariant();
is64bit = IsBitness64bit(comp);
deleteIndex = i;
break;
}
}
if (deleteIndex == -1)
{
return false;
}
components.Remove(deleteIndex);
components.SaveChanges();
RemoveClsidFromRegistry(is64bit, clsid);
}
catch (Exception e)
{
if (e is NullReferenceException || e is SEHException)
{
throw e;
}
ToolConsole.WriteWarning(SR.GetString(SR.FailedToRemoveListenerComponentFromApplication, applicationId, progid));
}
return true;
}
public static bool RemoveListener(Guid appid)
{
string application = appid.ToString("B");
string partitionId = null;
Guid listenerClsid;
string listenerProgid;
ICatalog2 catalog = GetCatalog();
partitionId = GetPartitionIdForApplication(catalog, application, false);
bool is64bit = GetApplicationBitness(catalog, partitionId, application);
if (FindListener(appid, out listenerClsid, out listenerProgid))
return RemoveComponent(catalog, partitionId, application, listenerProgid);
return false;
}
public static bool ResolveApplicationId(string appidOrName, out Guid appId)
{
ICatalogObject appObj = null;
ICatalogCollection appColl = null;
appId = Guid.Empty;
if (!FindApplication(appidOrName, out appObj, out appColl))
{
return false;
}
appId = new Guid((string)appObj.Key());
return true;
}
static void SetCurrentPartition(ICatalog2 catalog, string partitionId)
{
try
{
catalog.CurrentPartition(partitionId);
}
catch (Exception e)
{
if (e is NullReferenceException || e is SEHException)
{
throw e;
}
throw Tool.CreateException(SR.GetString(SR.CouldNotSetPartition), e);
}
}
public static void SetAppDir(string appidOrName, string path)
{
ICatalogObject appObj = null;
ICatalogCollection appColl = null;
if (!FindApplication(appidOrName, out appObj, out appColl))
{
throw Tool.CreateException(SR.GetString(SR.ApplicationNotFound, appidOrName), null);
}
appObj.SetValue(PropertyName.ApplicationDirectory, path);
appColl.SaveChanges();
}
}
class ComAdminAppInfo
{
string appdir;
Guid appid;
string appname;
bool serverActivated;
bool systemApplication;
bool processPooled;
bool automaticRecycling;
bool listenerExists;
List<ComAdminClassInfo> classes;
RuntimeVersions runtimeVersion;
static Guid CLSID_CLRMetaHost = new Guid("{9280188d-0e8e-4867-b30c-7fa83884e8de}");
static Guid CLSID_ServiceInitializer = new Guid("{59856830-3ECB-4D29-9CFE-DDD0F74B96A2}");
static List<Version> CLRVersions = new List<Version>(2) { new Version("2.0"), new Version("4.0") };
public string ApplicationDirectory { get { return this.appdir; } }
public Guid ID { get { return this.appid; } }
public string Name { get { return this.appname; } }
public List<ComAdminClassInfo> Classes { get { return this.classes; } }
public bool IsServerActivated { get { return this.serverActivated; } }
public bool IsSystemApplication { get { return this.systemApplication; } }
public bool IsProcessPooled { get { return this.processPooled; } }
public bool IsAutomaticRecycling { get { return this.automaticRecycling; } }
public bool ListenerExists { get { return this.listenerExists; } }
public RuntimeVersions RuntimeVersion { get { return this.runtimeVersion; } }
public ComAdminAppInfo(ICatalogObject appObj, ICatalogCollection appColl)
{
this.appid = new Guid((string)appObj.Key());
this.appname = (string)appObj.Name();
this.appdir = (string)appObj.GetValue(PropertyName.ApplicationDirectory);
// Note that casting to long would throw an InvalidCastException
this.serverActivated = ((int)appObj.GetValue(PropertyName.Activation)) == 1;
this.systemApplication = (bool)appObj.GetValue(PropertyName.IsSystem);
this.processPooled = ((int)appObj.GetValue(PropertyName.ConcurrentApps)) > 1;
this.automaticRecycling = (((int)appObj.GetValue(PropertyName.RecycleActivationLimit) > 0) ||
((int)appObj.GetValue(PropertyName.RecycleCallLimit) > 0) ||
((int)appObj.GetValue(PropertyName.RecycleLifetimeLimit) > 0) ||
((int)appObj.GetValue(PropertyName.RecycleMemoryLimit) > 0));
this.BuildClasses(appObj, appColl);
}
bool TryGetVersionFromString(StringBuilder versionStr, out Version version)
{
string versionString;
bool isSuccessful = false;
version = null;
if (versionStr[0] == 'v' || versionStr[0] == 'V')
{
int strLen = versionStr.Length - 1;
versionString = versionStr.ToString(1, strLen);
}
else
{
versionString = versionStr.ToString();
}
try
{
version = new Version(versionString);
isSuccessful = true;
}
catch (ArgumentException)
{
}
catch (FormatException)
{
}
catch (OverflowException)
{
}
return isSuccessful;
}
bool IsCLRVersionInstalled(Version clrVersion)
{
object pCLRMetaHost;
bool isRuntimeVersionDetermined = false;
if (SafeNativeMethods.ERROR_SUCCESS == SafeNativeMethods.CLRCreateInstance(CLSID_CLRMetaHost, typeof(IClrMetaHost).GUID, out pCLRMetaHost))
{
IClrMetaHost metaHost = (IClrMetaHost)pCLRMetaHost;
IEnumUnknown enumUnknownPtr;
enumUnknownPtr = metaHost.EnumerateInstalledRuntimes();
object[] pUnk = new object[1];
int pceltFetched;
while (SafeNativeMethods.ERROR_SUCCESS == enumUnknownPtr.Next(1, pUnk, out pceltFetched) && !isRuntimeVersionDetermined)
{
int bufferSize = 256;
StringBuilder builder = new StringBuilder(256);
IClrRuntimeInfo runtimeInfo = (IClrRuntimeInfo)pUnk[0];
runtimeInfo.GetVersionString(builder, ref bufferSize);
Version installedClrVersion;
if (TryGetVersionFromString(builder, out installedClrVersion))
{
if (clrVersion.Major == installedClrVersion.Major && clrVersion.Minor == installedClrVersion.Minor)
{
isRuntimeVersionDetermined = true;
}
}
}
}
return isRuntimeVersionDetermined;
}
bool ValidateCLRVersion(Version clrVersion)
{
foreach (Version releasedCLRVersion in CLRVersions)
{
if (clrVersion.Major == releasedCLRVersion.Major && clrVersion.Minor == releasedCLRVersion.Minor)
{
return true;
}
}
return false;
}
void BuildClasses(ICatalogObject appObj, ICatalogCollection appColl)
{
int versionStrSize = 256;
StringBuilder version = new StringBuilder(256);
bool isFrameworkVersionSet = false;
bool isRuntimeVersionSet = false;
bool isRuntimeVersionInstalled = true;
int length = 0;
Version appClrVersion = null;
this.classes = new List<ComAdminClassInfo>();
ICatalogCollection comps = (ICatalogCollection)appColl.GetCollection(CollectionName.Components, appObj.Key());
comps.Populate();
for (int i = 0; i < comps.Count(); i++)
{
ICatalogObject comp = (ICatalogObject)comps.Item(i);
ComAdminClassInfo classInfo = new ComAdminClassInfo(comp, comps);
isFrameworkVersionSet = false;
if (!isRuntimeVersionSet)
{
isFrameworkVersionSet = (SafeNativeMethods.ERROR_SUCCESS == SafeNativeMethods.GetRequestedRuntimeVersionForCLSID(classInfo.Clsid, version, versionStrSize, ref length, 0));
if (isFrameworkVersionSet && TryGetVersionFromString(version, out appClrVersion))
{
if (IsCLRVersionInstalled(appClrVersion))
{
isRuntimeVersionSet = true;
}
else if (ValidateCLRVersion(appClrVersion))
{
// We've found an valid CLR version in the app but that runtime version is not installed
isRuntimeVersionSet = true;
isRuntimeVersionInstalled = false;
}
}
}
if (ComAdminWrapper.IsListenerComponent(comp))
{
this.listenerExists = true;
}
else
{
this.classes.Add(classInfo);
}
}
//Parse the version number we get
// If the version is V4.0* we are going to register the 4.0 version of ServiceMonikerSupport.dll
// Anything else we are going to register the 3.0 version of ServiceMonikerSupport.dll
if (isRuntimeVersionSet && isRuntimeVersionInstalled)
{
if (appClrVersion.Major == 4 && appClrVersion.Minor == 0)
{
this.runtimeVersion = RuntimeVersions.V40;
}
else if (appClrVersion.Major == 2 && appClrVersion.Minor == 0)
{
this.runtimeVersion = RuntimeVersions.V20;
}
else
{
// It is non of the CLR version this tool recognize
throw Tool.CreateException(SR.GetString(SR.FailedToGetRuntime, appClrVersion.ToString()), null);
}
}
else if (!isRuntimeVersionInstalled)
{
// When we can't find the matching runtime for the user application, throw an application exception
throw Tool.CreateException(SR.GetString(SR.FailedToGetRuntime, appClrVersion.ToString()), null);
}
else
{
this.runtimeVersion = RuntimeVersions.V40;
}
}
public ComAdminClassInfo FindClass(string classNameOrGuid)
{
ComAdminClassInfo resolvedClassInfo = null;
classNameOrGuid = classNameOrGuid.ToLowerInvariant();
foreach (ComAdminClassInfo classInfo in this.classes)
{
if ((classInfo.Clsid.ToString("B").ToLowerInvariant() == classNameOrGuid)
|| classInfo.Name.ToLowerInvariant() == classNameOrGuid)
{
if (resolvedClassInfo == null)
{
resolvedClassInfo = classInfo;
}
else
{
throw Tool.CreateException(SR.GetString(SR.AmbiguousComponentName, classNameOrGuid), null);
}
}
}
return resolvedClassInfo;
}
}
class ComAdminClassInfo
{
Guid clsid;
List<ComAdminInterfaceInfo> interfaces;
bool isPrivate;
string progid;
TransactionOption transactionOption;
public Guid Clsid { get { return this.clsid; } }
public bool IsPrivate { get { return this.isPrivate; } }
public string Name { get { return this.progid; } }
public List<ComAdminInterfaceInfo> Interfaces { get { return this.interfaces; } }
public bool SupportsTransactionFlow
{
get
{
if ((transactionOption == TransactionOption.Required) ||
(transactionOption == TransactionOption.Supported))
return true;
else
return false;
}
}
public ComAdminClassInfo(ICatalogObject compObj, ICatalogCollection compColl)
{
this.clsid = new Guid((string)compObj.Key());
this.progid = (string)compObj.Name();
this.isPrivate = (bool)compObj.GetValue(PropertyName.IsPrivateComponent);
this.transactionOption = (TransactionOption)compObj.GetValue(PropertyName.TransactionOption);
this.BuildInterfaces(compObj, compColl);
}
void BuildInterfaces(ICatalogObject compObj, ICatalogCollection compColl)
{
this.interfaces = new List<ComAdminInterfaceInfo>();
ICatalogCollection interfaceColl = (ICatalogCollection)compColl.GetCollection(CollectionName.InterfacesForComponent, compObj.Key());
interfaceColl.Populate();
for (int i = 0; i < interfaceColl.Count(); i++)
{
ICatalogObject itf = (ICatalogObject)interfaceColl.Item(i);
Guid interfaceID = new Guid((string)itf.Key());
ComAdminInterfaceInfo interfaceInfo = new ComAdminInterfaceInfo(interfaceID, (string)itf.Name());
this.interfaces.Add(interfaceInfo);
}
}
public ComAdminInterfaceInfo FindInterface(string interfaceNameOrGuid)
{
ComAdminInterfaceInfo resolvedInterfaceInfo = null;
interfaceNameOrGuid = interfaceNameOrGuid.ToLowerInvariant();
foreach (ComAdminInterfaceInfo interfaceInfo in this.interfaces)
{
if ((interfaceInfo.Iid.ToString("B").ToLowerInvariant() == interfaceNameOrGuid.ToLowerInvariant())
|| interfaceInfo.Name.ToLowerInvariant() == interfaceNameOrGuid)
{
if (resolvedInterfaceInfo == null)
{
resolvedInterfaceInfo = interfaceInfo;
}
else
{
throw Tool.CreateException(SR.GetString(SR.AmbiguousInterfaceName, interfaceNameOrGuid), null);
}
}
}
return resolvedInterfaceInfo;
}
}
class ComAdminInterfaceInfo
{
Guid iid;
string name;
public Guid Iid { get { return this.iid; } }
public string Name { get { return this.name; } }
public ComAdminInterfaceInfo(Guid iid, string name)
{
this.iid = iid;
this.name = name;
}
}
}
|