N
Nikola Novak
Hello,
Here is the situation: I'm loading up various add-ins for my application
and I ran into trouble when one of my add-ins, which was placed in its own
subdirectory, failed to load its dependency (they were referenced under
"References").
The main program loads up two files of the add-in: AddIn.dll and
OtherAddIn.dll (both files are part of the same addin). OtherAddIn has -
among others - the AddInManager.dll in its references, but AddIn has both
AddInManager.dll and OtherAddIn.dll. I would like to have AddInManager
placed in the base application folder and all the addin files in their
respective subdirectories (\AddIns\Addin1, \AddIns\Addin2, etc.)
Moreover, AddIn is a user control, but it must also inherit the interface I
defined. OtherAddIn is a class library and inherits the other interface.
Searching the net for the solution I came across this article:
http://msdn.microsoft.com/en-us/magazine/cc163701.aspx
It is mainly concerned about the security of loading add-ins and not the
folder issue I have. However, I decided to implement it because it can also
help me with the folder issue and, of course, because security is
important.
The result was the following code:
In main.cs:
// ...
private IAddIn presenter1;
// ...
// this is called from constructor of the form with parameter value
// FileName = D:\MyAddInProject\AddIns\MyFirstAddIn\AddIn.DLL
private void LoadAddIn(string FileName)
{
Evidence LocalEvidence = new Evidence(new object[] { new Zone(SecurityZone.MyComputer) }, new object[] { });
PermissionSet LocalPermissions = SecurityManager.ResolvePolicy(LocalEvidence);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\AddIns\\MyFirstAddin";
AppDomain sandboxedDomain = AppDomain.CreateDomain("Add-In Domain", LocalEvidence, setup, LocalPermissions, new StrongName[] { });
Type addInManagerType = typeof(AddInManager);
AddInManager manager = (AddInManager)Activator.CreateInstanceFrom(sandboxedDomain, addInManagerType.Assembly.Location, addInManagerType.FullName).Unwrap();
// Program breaks on the following line with NullReferenceException
manager.SetParams(FileName, "AddIn.AddIn1");
presenter1 = manager.GetInterface();
Control ControlBoard = manager.GetControl();
//...
}
In AddInManager.cs:
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Security;
using System.Security.Permissions;
namespace Interfaces
{
public class AddInManager : MarshalByRefObject
{
private string _Assembly = "";
private string _Type = "";
private object _Instance;
public void SetParams(string AssemblyName, string AssemblyType)
{
// writing to disk for debugging purposes
StreamWriter Test = new StreamWriter("abcd.txt");
Test.WriteLine(AssemblyName + " " + AssemblyType);
Test.Flush();
_Assembly = AssemblyName;
_Type = AssemblyType;
Assembly a = Assembly.LoadFile(AssemblyName);
Test.WriteLine(a.Location);
Test.Flush();
Type t = a.GetType(AssemblyType);
Test.WriteLine((t == null) ? "Type is null." : "Success!");
Test.Flush();
// Output stops here because t == null
_Instance = t.InvokeMember(null, BindingFlags.CreateInstance, null, null, null);
Test.WriteLine("I'm out!");
Test.Close();
//Activator.CreateInstance(AssemblyName, AssemblyType);
}
// get the instance by casting it to the interface
// if this fails at this time, then there will be an exception
// that's good because everything's still in the tryout phase
public IAddIn GetInterface()
{
// one day this will be surrounded by a try/catch block
return (IAddIn)_Instance;
}
// get the instance by casting it to Control
// this I need because I need to access some of the methods and
// properties inherited from Control (so I don't need to force them
// all in the interface)
// if this fails at this time, then there will be an exception
// that's good because everything's still in the tryout phase
public Control GetControl()
{
// one day this will be surrounded by a try/catch block
return (Control)_Instance;
}
}
public interface IAddIn
{
System.Windows.Forms.BorderStyle Borderstyle { get; set; }
int FF { get; set; }
bool ShowMaxMoves { get; set; }
}
public interface IOtherAddIn
{
// ...
}
}
Contents of abcd.txt after execution:
D:\MyAddInProject\AddIns\MyFirstAddIn\AddIn.DLL AddIn.AddIn1
D:\MyAddInProject\AddIns\MyFirstAddIn\AddIn.DLL
Type is null.
Putting it short, what's going on in this code? I've never dealt with
security issues before and I basically have no clue what most of the
classes in LoadAddIn do.
Why does the variable t in AddInManager become null?
What am I doing wrong? (or better, what am I doing at all?)
Thanks,
Nikola
Here is the situation: I'm loading up various add-ins for my application
and I ran into trouble when one of my add-ins, which was placed in its own
subdirectory, failed to load its dependency (they were referenced under
"References").
The main program loads up two files of the add-in: AddIn.dll and
OtherAddIn.dll (both files are part of the same addin). OtherAddIn has -
among others - the AddInManager.dll in its references, but AddIn has both
AddInManager.dll and OtherAddIn.dll. I would like to have AddInManager
placed in the base application folder and all the addin files in their
respective subdirectories (\AddIns\Addin1, \AddIns\Addin2, etc.)
Moreover, AddIn is a user control, but it must also inherit the interface I
defined. OtherAddIn is a class library and inherits the other interface.
Searching the net for the solution I came across this article:
http://msdn.microsoft.com/en-us/magazine/cc163701.aspx
It is mainly concerned about the security of loading add-ins and not the
folder issue I have. However, I decided to implement it because it can also
help me with the folder issue and, of course, because security is
important.
The result was the following code:
In main.cs:
// ...
private IAddIn presenter1;
// ...
// this is called from constructor of the form with parameter value
// FileName = D:\MyAddInProject\AddIns\MyFirstAddIn\AddIn.DLL
private void LoadAddIn(string FileName)
{
Evidence LocalEvidence = new Evidence(new object[] { new Zone(SecurityZone.MyComputer) }, new object[] { });
PermissionSet LocalPermissions = SecurityManager.ResolvePolicy(LocalEvidence);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "\\AddIns\\MyFirstAddin";
AppDomain sandboxedDomain = AppDomain.CreateDomain("Add-In Domain", LocalEvidence, setup, LocalPermissions, new StrongName[] { });
Type addInManagerType = typeof(AddInManager);
AddInManager manager = (AddInManager)Activator.CreateInstanceFrom(sandboxedDomain, addInManagerType.Assembly.Location, addInManagerType.FullName).Unwrap();
// Program breaks on the following line with NullReferenceException
manager.SetParams(FileName, "AddIn.AddIn1");
presenter1 = manager.GetInterface();
Control ControlBoard = manager.GetControl();
//...
}
In AddInManager.cs:
using System;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Security;
using System.Security.Permissions;
namespace Interfaces
{
public class AddInManager : MarshalByRefObject
{
private string _Assembly = "";
private string _Type = "";
private object _Instance;
public void SetParams(string AssemblyName, string AssemblyType)
{
// writing to disk for debugging purposes
StreamWriter Test = new StreamWriter("abcd.txt");
Test.WriteLine(AssemblyName + " " + AssemblyType);
Test.Flush();
_Assembly = AssemblyName;
_Type = AssemblyType;
Assembly a = Assembly.LoadFile(AssemblyName);
Test.WriteLine(a.Location);
Test.Flush();
Type t = a.GetType(AssemblyType);
Test.WriteLine((t == null) ? "Type is null." : "Success!");
Test.Flush();
// Output stops here because t == null
_Instance = t.InvokeMember(null, BindingFlags.CreateInstance, null, null, null);
Test.WriteLine("I'm out!");
Test.Close();
//Activator.CreateInstance(AssemblyName, AssemblyType);
}
// get the instance by casting it to the interface
// if this fails at this time, then there will be an exception
// that's good because everything's still in the tryout phase
public IAddIn GetInterface()
{
// one day this will be surrounded by a try/catch block
return (IAddIn)_Instance;
}
// get the instance by casting it to Control
// this I need because I need to access some of the methods and
// properties inherited from Control (so I don't need to force them
// all in the interface)
// if this fails at this time, then there will be an exception
// that's good because everything's still in the tryout phase
public Control GetControl()
{
// one day this will be surrounded by a try/catch block
return (Control)_Instance;
}
}
public interface IAddIn
{
System.Windows.Forms.BorderStyle Borderstyle { get; set; }
int FF { get; set; }
bool ShowMaxMoves { get; set; }
}
public interface IOtherAddIn
{
// ...
}
}
Contents of abcd.txt after execution:
D:\MyAddInProject\AddIns\MyFirstAddIn\AddIn.DLL AddIn.AddIn1
D:\MyAddInProject\AddIns\MyFirstAddIn\AddIn.DLL
Type is null.
Putting it short, what's going on in this code? I've never dealt with
security issues before and I basically have no clue what most of the
classes in LoadAddIn do.
Why does the variable t in AddInManager become null?
What am I doing wrong? (or better, what am I doing at all?)
Thanks,
Nikola