如何检查程序集的类型是否为 ComVisible
How to check if type from assembly is ComVisible
我正在为 Enterprise Architect 编写插件管理器。
加载程序集(加载项 dll)时,我需要知道程序集中定义的哪些类型是 COM 可见的,因此我可以添加所需的注册表项以将其注册为 COM 互操作。
这是我目前所拥有的:
public EAAddin(string fileName):base()
{
//load the dll
this.addinDLL = Assembly.LoadFrom(fileName);
//register the COM visible classes
this.registerClasses(this.addinDLL);
//load referenced dll's
foreach (AssemblyName reference in this.addinDLL.GetReferencedAssemblies())
{
if (System.IO.File.Exists(
System.IO.Path.GetDirectoryName(this.addinDLL.Location) +
@"\" + reference.Name + ".dll"))
{
Assembly referencedAssembly = System.Reflection.Assembly.LoadFrom(System.IO.Path.GetDirectoryName(this.addinDLL.Location) + @"\" + reference.Name + ".dll");
//register the COM visible classes for the registered assembly
this.registerClasses(referencedAssembly);
// ... more code ...
private void registerClasses (Assembly assembly)
{
foreach (Type type in assembly.GetExportedTypes())
{
register(type, assembly);
}
}
private void register(Type type, Assembly assembly)
{
var attributes = type.GetCustomAttributes(typeof(ComVisibleAttribute),false);
if (attributes.Length > 0)
{
ComVisibleAttribute comvisible = (ComVisibleAttribute)attributes[0];
if (comvisible.Value == true)
{
//TODO add registry keys here
}
}
}
这不起作用,因为类型似乎不包含 ComVisibleAttribute。
有人知道如何找出程序集中的哪些导出类型是 COM 可见的吗?
多亏了 Paulo 的评论,我才弄明白了。
如果类型与程序集默认值不同,则该类型只有 ComVisibleAttribute。
所以这个操作(在返回的类型之一上调用 Assembly.GetExportedTypes()
)似乎可以解决问题
/// <summary>
/// Check if the given type is ComVisible
/// </summary>
/// <param name="type">the type to check</param>
/// <returns>whether or not the given type is ComVisible</returns>
private bool isComVisible(Type type)
{
bool comVisible = true;
//first check if the type has ComVisible defined for itself
var typeAttributes = type.GetCustomAttributes(typeof(ComVisibleAttribute),false);
if (typeAttributes.Length > 0)
{
comVisible = ((ComVisibleAttribute)typeAttributes[0]).Value;
}
else
{
//no specific ComVisible attribute defined, return the default for the assembly
var assemblyAttributes = type.Assembly.GetCustomAttributes(typeof(ComVisibleAttribute),false);
if (assemblyAttributes.Length > 0)
{
comVisible = ((ComVisibleAttribute)assemblyAttributes[0]).Value;
}
}
return comVisible;
}
我正在为 Enterprise Architect 编写插件管理器。
加载程序集(加载项 dll)时,我需要知道程序集中定义的哪些类型是 COM 可见的,因此我可以添加所需的注册表项以将其注册为 COM 互操作。
这是我目前所拥有的:
public EAAddin(string fileName):base()
{
//load the dll
this.addinDLL = Assembly.LoadFrom(fileName);
//register the COM visible classes
this.registerClasses(this.addinDLL);
//load referenced dll's
foreach (AssemblyName reference in this.addinDLL.GetReferencedAssemblies())
{
if (System.IO.File.Exists(
System.IO.Path.GetDirectoryName(this.addinDLL.Location) +
@"\" + reference.Name + ".dll"))
{
Assembly referencedAssembly = System.Reflection.Assembly.LoadFrom(System.IO.Path.GetDirectoryName(this.addinDLL.Location) + @"\" + reference.Name + ".dll");
//register the COM visible classes for the registered assembly
this.registerClasses(referencedAssembly);
// ... more code ...
private void registerClasses (Assembly assembly)
{
foreach (Type type in assembly.GetExportedTypes())
{
register(type, assembly);
}
}
private void register(Type type, Assembly assembly)
{
var attributes = type.GetCustomAttributes(typeof(ComVisibleAttribute),false);
if (attributes.Length > 0)
{
ComVisibleAttribute comvisible = (ComVisibleAttribute)attributes[0];
if (comvisible.Value == true)
{
//TODO add registry keys here
}
}
}
这不起作用,因为类型似乎不包含 ComVisibleAttribute。
有人知道如何找出程序集中的哪些导出类型是 COM 可见的吗?
多亏了 Paulo 的评论,我才弄明白了。 如果类型与程序集默认值不同,则该类型只有 ComVisibleAttribute。
所以这个操作(在返回的类型之一上调用 Assembly.GetExportedTypes()
)似乎可以解决问题
/// <summary>
/// Check if the given type is ComVisible
/// </summary>
/// <param name="type">the type to check</param>
/// <returns>whether or not the given type is ComVisible</returns>
private bool isComVisible(Type type)
{
bool comVisible = true;
//first check if the type has ComVisible defined for itself
var typeAttributes = type.GetCustomAttributes(typeof(ComVisibleAttribute),false);
if (typeAttributes.Length > 0)
{
comVisible = ((ComVisibleAttribute)typeAttributes[0]).Value;
}
else
{
//no specific ComVisible attribute defined, return the default for the assembly
var assemblyAttributes = type.Assembly.GetCustomAttributes(typeof(ComVisibleAttribute),false);
if (assemblyAttributes.Length > 0)
{
comVisible = ((ComVisibleAttribute)assemblyAttributes[0]).Value;
}
}
return comVisible;
}