Skip to content

Instantly share code, notes, and snippets.

@caiorss
Forked from DevJohnC/ManifestReader.cs
Created December 19, 2016 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caiorss/2734d99ade721af8e659180784da4d11 to your computer and use it in GitHub Desktop.
Save caiorss/2734d99ade721af8e659180784da4d11 to your computer and use it in GitHub Desktop.
Reading a custom attribute from an assembly without loading it for execution.
//
// Author: John Carruthers (johnc@frag-labs.com)
//
// Copyright (C) 2014 John Carruthers
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Linq;
using AdjutantFramework.Plugins.Domains;
using IKVM.Reflection;
using Assembly = System.Reflection.Assembly;
namespace AdjutantFramework.Plugins.Assemblies
{
/// <summary>
/// Reads plugin manifests from assemblies without loading them.
/// </summary>
public class ManifestReader : DomainShareObject
{
public string AssemblyFileName { get; private set; }
public ManifestReader(string assemblyFileName)
{
AssemblyFileName = assemblyFileName;
if (assemblyFileName == null) throw new ArgumentNullException("assemblyFileName");
}
/// <summary>
/// Reads the plugin manifest from the assembly.
/// </summary>
/// <returns></returns>
public PluginManifestAttribute ReadManifestAttribute()
{
if (File.Exists(AssemblyFileName))
{
var universe = new Universe();
universe.AssemblyResolve += (sender, args) =>
{
return null;
};
var mscorlib = universe.LoadFile(typeof(Assembly).Assembly.Location);
// todo: use the assembly resolver here instead of hard coded path.
var apiAsm = universe.LoadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Framework.dll"));
var ikvmManifestType = apiAsm.GetType(typeof(PluginManifestAttribute).FullName);
var ikvmAsm = universe.LoadFile(AssemblyFileName);
var attrs = ikvmAsm.__GetCustomAttributes(ikvmManifestType, false).FirstOrDefault();
if (attrs == null)
return null;
var pluginName = attrs.ConstructorArguments[0].Value as string;
var pluginId = attrs.ConstructorArguments[1].Value as string;
var pluginVersion = attrs.ConstructorArguments[2].Value as string;
var author = attrs.ConstructorArguments[3].Value as string;
var websiteUrl = attrs.ConstructorArguments[4].Value as string;
var emailAddress = attrs.ConstructorArguments[5].Value as string;
var copyright = attrs.ConstructorArguments[6].Value as string;
universe.Dispose();
return new PluginManifestAttribute(pluginName, pluginId, pluginVersion, author,
websiteUrl, emailAddress, copyright);
}
return null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment