// The Nova Project by Ken Beckett.
// Copyright (C) 2007-2012 Inevitable Software, all rights reserved.
// Released under the Common Development and Distribution License, CDDL-1.0: http://opensource.org/licenses/cddl1.php
using System;
using System.IO;
using System.Xml;
using Nova.Utilities;
namespace Nova.CodeDOM
{
/// <summary>
/// Represents a project reference to a COM object.
/// </summary>
public class COMReference : Reference
{
#region /* FIELDS */
protected Guid _guid;
protected string _versionMajor;
protected string _versionMinor;
protected int? _lcid;
protected string _wrapperTool;
protected bool? _isolated;
protected bool? _embedInteropTypes;
#endregion
#region /* CONSTRUCTORS */
/// <summary>
/// Create a new <see cref="COMReference"/> with the specified name and other parameters.
/// </summary>
public COMReference(string name, Guid guid, string versionMajor, string versionMinor)
: base(name, false)
{
_guid = guid;
_versionMajor = versionMajor;
_versionMinor = versionMinor;
}
#endregion
#region /* PROPERTIES */
/// <summary>
/// The unique identifier of the referenced COM object.
/// </summary>
public Guid Guid
{
get { return _guid; }
}
/// <summary>
/// The major version numbr of the referenced COM object.
/// </summary>
public string VersionMajor
{
get { return _versionMajor; }
}
/// <summary>
/// The minor version numbr of the referenced COM object.
/// </summary>
public string VersionMinor
{
get { return _versionMinor; }
}
/// <summary>
/// The LC ID number, or null if not used.
/// </summary>
public int? Lcid
{
get { return _lcid; }
set { _lcid = value; }
}
/// <summary>
/// The name of an associated wrapper tool.
/// </summary>
public string WrapperTool
{
get { return _wrapperTool; }
set { _wrapperTool = value; }
}
/// <summary>
/// True if isolated, null if not used.
/// </summary>
public bool? Isolated
{
get { return _isolated; }
set { _isolated = value; }
}
/// <summary>
/// True if interop types should be embedded, null if not used.
/// </summary>
public bool? EmbedInteropTypes
{
get { return _embedInteropTypes; }
set { _embedInteropTypes = value; }
}
/// <summary>
/// The descriptive category of the code object.
/// </summary>
public override string Category
{
get { return "COM Object"; }
}
#endregion
#region /* METHODS */
/// <summary>
/// Load the reference.
/// </summary>
public override void Load()
{
// Look in the registry to find the display name of the assembly for the COM object, and load it
string errorMessage = null;
string registryPath = @"TypeLib\" + _guid.ToString("B") + @"\" + _versionMajor + "." + _versionMinor;
string displayName = RegistryUtil.GetClassesString(registryPath, "PrimaryInteropAssemblyName");
if (displayName != null)
errorMessage = LoadAssembly(displayName);
// If we failed to load using the registry info, try looking for an interop file in the output directory
Project parentProject = ParentProject;
if (_loadedAssembly == null && parentProject != null)
{
string fileName;
if (_name.StartsWith("Ax"))
fileName = "AxInterop." + _name.Substring(2) + ".dll";
else
fileName = "Interop." + _name + ".dll";
string assemblyPath = Path.Combine(parentProject.GetFullOutputPath() ?? "", fileName);
errorMessage = LoadAssembly(assemblyPath);
}
if (errorMessage != null)
LogAndAttachMessage(errorMessage, MessageSeverity.Error, MessageSource.Load);
}
#endregion
#region /* PARSING */
/// <summary>
/// Parse from the specified <see cref="XmlReader"/>.
/// </summary>
public COMReference(XmlReader xmlReader, Project project)
: base(project)
{
try
{
if (xmlReader.MoveToAttribute("Include"))
{
_name = xmlReader.Value;
xmlReader.MoveToElement();
if (!xmlReader.IsEmptyElement)
{
while (xmlReader.Read())
{
if (xmlReader.IsStartElement())
{
if (xmlReader.Name == "Guid")
_guid = Guid.Parse(xmlReader.ReadString());
else if (xmlReader.Name == "VersionMajor")
_versionMajor = xmlReader.ReadString();
else if (xmlReader.Name == "VersionMinor")
_versionMinor = xmlReader.ReadString();
else if (xmlReader.Name == "Lcid")
_lcid = StringUtil.ParseInt(xmlReader.ReadString());
else if (xmlReader.Name == "WrapperTool")
_wrapperTool = StringUtil.EmptyAsNull(xmlReader.ReadString());
else if (xmlReader.Name == "Isolated")
_isolated = StringUtil.ParseBool(xmlReader.ReadString());
else if (xmlReader.Name == "EmbedInteropTypes")
_embedInteropTypes = StringUtil.ParseBool(xmlReader.ReadString());
else if (xmlReader.Name == "Aliases")
Alias = xmlReader.ReadString();
}
if (xmlReader.NodeType == XmlNodeType.EndElement && xmlReader.Name == "COMReference")
break;
}
}
}
}
catch (Exception ex)
{
LogAndAttachException(ex, "parsing", MessageSource.Parse);
}
}
#endregion
#region /* RENDERING */
/// <summary>
/// Write to the specified <see cref="XmlWriter"/>.
/// </summary>
public override void AsText(XmlWriter xmlWriter)
{
xmlWriter.WriteStartElement("COMReference");
xmlWriter.WriteAttributeString("Include", _name);
xmlWriter.WriteElementString("Guid", _guid.ToString("B").ToUpper());
if (_versionMajor != null)
xmlWriter.WriteElementString("VersionMajor", _versionMajor);
if (_versionMinor != null)
xmlWriter.WriteElementString("VersionMinor", _versionMinor);
if (_lcid != null)
xmlWriter.WriteElementString("Lcid", _lcid.GetValueOrDefault().ToString());
if (_wrapperTool != null)
xmlWriter.WriteElementString("WrapperTool", _wrapperTool);
if (_isolated != null)
xmlWriter.WriteElementString("Isolated", _isolated.GetValueOrDefault().ToString());
if (_embedInteropTypes != null)
xmlWriter.WriteElementString("EmbedInteropTypes", _embedInteropTypes.GetValueOrDefault().ToString());
if (_alias != null)
xmlWriter.WriteElementString("Aliases", _alias);
xmlWriter.WriteEndElement();
}
#endregion
}
}