How can I make SourceAFIS work on Ubuntu? - c#

I am trying to use SourceAFIS 1.7.0 on Ubuntu with mono and get a few error.
1.
$ mono DatabaseAnalyzer.exe
Scanning folder TestDatabase
Running extractor benchmark
Unhandled Exception: System.IO.FileNotFoundException: Could not load
file or assembly 'PresentationCore, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
File name: 'PresentationCore, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'
at DatabaseAnalyzer.DatabaseAnalyzer.RunExtractorBenchmark ()
<0x40674790
+ 0x00033> in :0 at DatabaseAnalyzer.DatabaseAnalyzer.RunMatcherBenchmark () <0x40674600 +
0x000eb> in :0
at DatabaseAnalyzer.DatabaseAnalyzer.Run () <0x40642a40 + 0x000bf> in
:0
at DatabaseAnalyzer.DatabaseAnalyzer.Main (System.String[] args)
<0x4063bd50 + 0x00037> in :0
[ERROR] FATAL UNHANDLED EXCEPTION: System.IO.FileNotFoundException:
Could not load file or assembly 'PresentationCore, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its
dependencies.
File name: 'PresentationCore, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35' at
DatabaseAnalyzer.DatabaseAnalyzer.RunExtractorBenchmark () <0x40674790
+ 0x00033> in :0 at DatabaseAnalyzer.DatabaseAnalyzer.RunMatcherBenchmark () <0x40674600 +
0x000eb> in :0
at DatabaseAnalyzer.DatabaseAnalyzer.Run () <0x40642a40 + 0x000bf> in
:0
at DatabaseAnalyzer.DatabaseAnalyzer.Main (System.String[] args)
<0x4063bd50 + 0x00037> in :0
According to https://sourceforge.net/p/sourceafis/discussion/1051112/thread/dd8df289/#a006, WinForms should be applied here instead of WPF and use bitmap class to replace the bitmapimage class of WPF, but I don't know how to do it exactly. Does anybody have such experience?
This is the original function used WPF bitmap class
static MyPerson Enroll(string filename, string name)
{
Console.WriteLine("Enrolling {0}...", name);
// Initialize empty fingerprint object and set properties
MyFingerprint fp = new MyFingerprint();
fp.Filename = filename;
// Load image from the file
Console.WriteLine(" Loading image from {0}...", filename);
BitmapImage image = new BitmapImage(new Uri(filename, UriKind.RelativeOrAbsolute));
fp.AsBitmapSource = image;
// Above update of fp.AsBitmapSource initialized also raw image in fp.Image
// Check raw image dimensions, Y axis is first, X axis is second
Console.WriteLine(" Image size = {0} x {1} (width x height)", fp.Image.GetLength(1), fp.Image.GetLength(0));
// Initialize empty person object and set its properties
MyPerson person = new MyPerson();
person.Name = name;
// Add fingerprint to the person
person.Fingerprints.Add(fp);
// Execute extraction in order to initialize fp.Template
Console.WriteLine(" Extracting template...");
Afis.Extract(person);
// Check template size
Console.WriteLine(" Template size = {0} bytes", fp.Template.Length);
return person;
}
$ mono SourceAFIS.FingerprintAnalysis.exe
The entry point method could not be loaded
How can I fix this with a more meaningful exception?

WinForms should be applied here instead of WPF and use bitmap class to
replace the bitmapimage class of WPF, but I don't know how to do it
exactly. Does anybody have such experience?
Do you know how to program in C# language? What they mean in that forum is that you need to change the code to not use the WPF library, but Windows Forms UI toolkit.
If you get exceptions trying to load "PresentationCore" at runtime, it means it's still trying to load WPF.

Try installing mono-complete package, e.g.
apt-get install mono-complete
Related: Mono, failing to open executable.
Also make sure you've .NET Framework installed, e.g. by using winetricks:
apt-get install winetricks
winetricks dotnet46
See: Could not load file or assembly 'PresentationCore'.
PresentationCore is .NET 4
Further more, you can try the following suggestions:
In IIS try to Enable 32-Bit Applications in the Application Pools's Advanced Settings
Configure authentication as follow:
Disable Anonymous Authentication.
Enable ASP.NET Impersonation.
Enable Windows Authentication.

Related

Creating a signalR client HubConnection with Powershell

I am trying to connect to a SignalR hub using a powershell script. I am very new to powershell, so please excuse any rookie mistake.
I have set up a minimal not working example of what I have tried here :
Gist
Relevant code:
Load dlls
$dllFolder = -join((Get-Item -Path ".\" -Verbose).FullName, "\bin\Debug\")
[string[]] $dllPathsToLoad = #("\Newtonsoft.Json.dll", "\Microsoft.AspNet.SignalR.Client.dll")
$token = "insertyourtokenhere"
function LoadDllPaths($dlls)
{
foreach ($dll in $dlls)
{
$dllpath = $dllFolder + $dll
[System.Reflection.Assembly]::LoadFrom($dllpath)
}
}
[...]
LoadDllPaths($dllPathsToLoad)
Create HubConnection:
$server = "https://localhost/rest/"
[...]
$hub = New-Object Microsoft.AspNet.SignalR.Client.HubConnection($server)
Steps:
Create a new Visual Studio project
Add Newtonsoft.Json v10.0.2 Nuget package (latest)
Add Microsoft.AspNet.SignalR.Client v2.2.2 Nuget package (latest)
Add powershell script to the root of the project
With powershell (run as admin), type .\HubConnectionTestsScript.ps1
Result:
View on imgur
Error : System.Management.Automation.MethodInvocationException: Exception calling ".ctor" with "1" argument(s): "Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified." ---> System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
at Microsoft.AspNet.SignalR.Client.Connection..ctor(String url, String queryString)
at Microsoft.AspNet.SignalR.Client.HubConnection..ctor(String url, Boolean useDefaultUrl)
--- End of inner exception stack trace ---
at System.Management.Automation.DotNetAdapter.AuxiliaryConstructorInvoke(MethodInformation methodInformation, Object[] arguments, Object[] originalArguments)
at System.Management.Automation.DotNetAdapter.ConstructorInvokeDotNet(Type type, ConstructorInfo[] constructors, Object[] arguments)
at Microsoft.PowerShell.Commands.NewObjectCommand.CallConstructor(Type type, ConstructorInfo[] constructors, Object[] args)
This signalR source code object seems to be the problem, I just don't see what part of it can be throwing this error.
Question:
Why does the error mention Newtonsoft.Json v6.0.0 when signalR dependencies say >=6.0.4, and I have 10.0.2?
Am I doing anything wrong in my Powershell script which could be causing this?
Thank you very much! Any help is appreciated at this point
I managed to solve this issue with some help from a colleague. Sharing the solution here in case anyone ever struggles on the same problem.
It appears that one of SignalR dependencies tries to load an old version of Newtonsoft.Json. We can force it to redirect him to our own instance of Newtonsoft.Json
Inspired by this gist, here is the idea :
When you load your Json Assembly, store it in a variable
$newtonsoftAssembly = [System.Reflection.Assembly]::LoadFrom($dllFolder + "\Newtonsoft.Json.dll")
Afterwards, setup the redirect bindings. My best guess is that this intercepts any call to load an assembly, giving us the opportunity to return our own Json assembly instead of letting him fail to find the version he wants (6.0.0 in my case).
function RedirectJsonBindings()
{
$onAssemblyResolveEventHandler = [System.ResolveEventHandler] {
param($sender, $e)
# You can make this condition more or less version specific as suits your requirements
if ($e.Name.StartsWith("Newtonsoft.Json")) {
Write-Host "Newtonsoft assembly" $e.Name -ForegroundColor DarkGreen
return $newtonsoftAssembly
}
foreach($assembly in [System.AppDomain]::CurrentDomain.GetAssemblies()) {
if ($assembly.FullName -eq $e.Name) {
return $assembly
}
}
return $null
}
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($onAssemblyResolveEventHandler)
}
And finally, at the end of your script, unbind
# Detach the event handler (not detaching can lead to stack overflow issues when closing PS)
[System.AppDomain]::CurrentDomain.remove_AssemblyResolve($onAssemblyResolveEventHandler)

C#, Get DLLs referenced by Activator.CreateInstance(assemblyType) object

I have a console app that resides in C:\MyApp.
I have several libraries that are NOT referenced by the app. I use an Activator.CreateInstance() to use them. They reside in C:\MyLibrary\Job001, C:\MyLibrary\Job002, etc. Each of these libraries have multiple dependencies and can be different versions of dependencies already found in the main app.
When I try to run this I am seeing this error: Could not load file or assembly 'Persistence.Database, Version=1.7.2.67, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. This is one of the common dependencies for most jobs. I checked the directory and it does exist with the library.
How do I activate the library AND have it use the references as found in it's own directory?
I am using the following (extension) code to activate a library:
public static IJob ConcreteJob(this JobInfoPayload src)
{
if (src.AssemblyFile.IsNullOrEmpty())
throw new Exception("AssemblyFile cannot be empty or null!");
if (src.AssemblyName.IsNullOrEmpty())
throw new Exception("AssemblyName cannot be empty or null!");
try
{
var assembly = Assembly.LoadFile(src.AssemblyFile);
var assemblyType = assembly.GetType(src.AssemblyName);
var job = Activator.CreateInstance(assemblyType) as IJob;
return job;
}
catch (Exception ex)
{
Serilog.Log.Logger.Fatal(ex, "JOB was not able to be created!!");
throw; // bubble this up to the top...
}
}
I am looking at system.appdomain.assemblyresolve but am not making sense of how to use this in the library project.
Thoughts?
ADDITIONAL INFO (29 NOV 2016)
Server App References:
Library.Infrastructure
QueueApp.Core
Hangfire
OWIN
Job Library References:
Library.Infrastructure
Library.Persistence
Library.SQL.Database01
Library.SQL.Database02
QueueApp.Job.Core
EntityFramework
We have several Jobs that follow the same pattern BUT can be built with different versions of the Job Library References. This is due to a slow creep over time. If a job written last year is still working why would we take the time to open up that solution, update all the references, recompile, then spend a month going back through QA and acceptance when we can just leave it alone?
The challenge I am running into is the JOB cannot find the referenced files, expecting them to be in the Server App directory. Instead, they are in that Job's directory. Using Fuslogvw.exe just confirms that it is NOT looking in the DLL's directory but rather the hosting app's directory.
** I currently get the same behavior whether I use Assembly.LoadFrom() or Assembly.LoadFile().
FUSLOGVW log results:
*** Assembly Binder Log Entry (11/29/2016 # 10:20:21 AM) ***
The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable D:\Dev\QueueApp\Source\QueueApp\bin\Debug\QueueApp.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: DisplayName = Job.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null (Fully-specified)
LOG: Appbase = file:///D:/Dev/QueueApp/Source/QueueApp/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = QueueApp.exe
Calling assembly : Job.AgileExport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: D:\Dev\QueueApp\Source\QueueApp\bin\Debug\QueueApp.exe.Config
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: Attempting download of new URL file:///D:/Dev/QueueApp/Source/QueueApp/bin/Debug/Job.Core.DLL.
LOG: Attempting download of new URL file:///D:/Dev/QueueApp/Source/QueueApp/bin/Debug/Job.Core/Job.Core.DLL.
LOG: Attempting download of new URL file:///D:/Dev/QueueApp/Source/QueueApp/bin/Debug/Job.Core.EXE.
LOG: Attempting download of new URL file:///D:/Dev/QueueApp/Source/QueueApp/bin/Debug/Job.Core/Job.Core.EXE.
LOG: All probing URLs attempted and failed.
The APP is looking for all files in:
D:\Dev\QueueApp\Source\QueueApp\bin\Debug
The JOB exists in:
D:\Dev\QueueApp\Source\Job.AgileExport\bin\Debug
I think there are two solutions available.
One solution is to create a new AppDomain to host your dynamically loaded assembly. When you create a new AppDomain you have the option of providing a settings object for the AppDomain, and in that object you get to provide the paths that AppDomain will use to resolve assemblies. You can't alter the paths in your existing AppDomain because it already exists.
Another solution is to handle your current AppDomain's AssemblyResolve event, which will be raised in the case that the normal assembly resolution fails. You can then take custom steps to help resolve the assembly.
There is a feature/bug in .NET where handling this event is required when .NET is hosted in various containers (such as IE, COM+, and more) and BinaryFormatter is used to deserialize types that should be available, but actually aren't found.
I have an example of hooking and resolving the AssemblyResolve event here:
https://github.com/MarimerLLC/csla/blob/V1-5-x/cslacs10/NetRun/Launcher.cs
In your case you can probably alter my ResolveEventHandler method to look for the "missing" assemblies in the folder where you originally loaded the dynamic assembly.
Using Assembly.LoadFrom, it is not possible to load multiple versions of the same assembly, in the same AppDomain.
Thus, if Job001 needs LibraryA, 1.0.0.0 (and can't use newer version at runtime) and Job002 needs LibraryA, 2.0.0.0, you'll have to load Job001 and Job002 each in its own AppDomain.
Notice that the order in which you dynamically load assemblies is very important:
When you load Job001 it will automatically load LibraryA, 1.0.0.0 if it finds it, and if you load Job002 after that, it won't be able to load LibraryA, 2.0.0.0 and LibraryA, 1.0.0.0 will remain in the domain.
Likewise, When you load Job002 it will automatically load LibraryA, 2.0.0.0 if it finds it, and if you load Job001 after that, it won't be able to load LibraryA, 1.0.0.0 and LibraryA, 2.0.0.0 will remain in the domain.
You best bet is to either use Assembly.LoadFile + AppDomain.AssemblyResolve to load the dependencies yourself (and then you can have multiple versions of the same assembly in the same AppDomain), or you create a separate AppDomain for each JobXXX assembly, and let the dependencies be loaded automatically.
This is what I came up with so far. These classes are in the main server app, not found in any of the JOBs. We have several different types of JOBs, Ad Hoc being one of the types. By placing the code in the base class, all JOB handlers now inherit it.
public class JobAdHocHandler : BaseHandler, IJobHandler
{
public MinimumResultModel Handle(MinimumCommandModel message)
{
var result = new MinimumResultModel {Id = "-1", PayloadAsString = message.FullPayloadString};
try
{
var info = message.MinimumPayload.JobInfo;
SetupInstance(info); // <<-- SOLUTION (in BaseHandler)
var job = JobHandler.GetJob(info); // <<-- SOLUTION (in BaseHandler)
result.Id = BackgroundJob.Enqueue(() => job.Execute(null, message.FullPayloadString, JobCancellationToken.Null));
}
catch (Exception ex)
{
Log.Logger.Fatal(ex, ex.Message);
result.Exception = ex;
}
AppDomain.Unload(JobAppDomain);
return result;
}
public bool AppliesTo(JobType jobType) => jobType == JobType.AdHoc;
}
public class BaseHandler : MarshalByRefObject
{
protected internal AppDomain JobAppDomain;
protected internal BaseHandler JobHandler;
protected internal void SetupInstance(JobInfoPayload info)
{
var ads = new AppDomainSetup
{
ApplicationBase = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName,
DisallowBindingRedirects = false,
DisallowCodeDownload = true,
PrivateBinPath = info.JobClassName,
ApplicationName = info.JobName,
};
JobAppDomain = AppDomain.CreateDomain(info.JobName, null, ads);
JobHandler = (BaseHandler)JobAppDomain.CreateInstanceAndUnwrap(typeof(BaseHandler).Assembly.FullName, typeof(BaseHandler).FullName);
}
protected internal IJob GetJob(JobInfoPayload info)
{
var assembly = Assembly.LoadFrom(info.JobClassName + #"\" + info.JobClassName + ".dll");
var assemblyType = assembly.GetType(info.AssemblyName);
var job = Activator.CreateInstance(assemblyType) as IJob;
if (job == null)
throw new Exception("Unable to create job: " + info.JobClassName);
return job;
}
}
Seems to work well so far.

TypeLoadException with D3DotNetAPI

I'm trying to use the D3DotNetAPI to create a Windows Phone 7 application.
Here is the link with the documentation : D3DotNetAPI documentation link
I'm just trying to follow the sample and to do this :
D3Explorer explorer = new D3Explorer(Region.EU);
//Career data for Battletag Gaidin#2380
Career myCareer = explorer.GetCareer("Gaidin", 2380);
MessageBox.Show("Has killed "+ myCareer.Kills.Monsters+" monstters, with "+ myCareer.Kills.Elites+" elites.");
And I throw this exception :
System.TypeLoadException: Could not load type 'System.Runtime.Serialization.ISerializable' from assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'.
at D3DotNetAPI.D3Explorer.TryGetData[T](String url, T& requestedObject)
at D3DotNetAPI.D3Explorer.GetCareer(String battleTagName, Int32 battleTagCode)
at d3.MainPage..ctor()
I'm not sure, but my exception can be similar with this stack overflow answer
PS : The same example works fine on a Win32 application.
Auto Answer :
ISerializable is not available in WP (WP = a part of .NET framework)

"Could not load file or assembly 'System.Core, Version=2.0.5.0,..." exception when loading Portable Class Library dynamically

First of all I need to emphasize that this is slightly different question than the one in this thread. Additionally, installing KB2468871 doesn't help.
I tried to simplify this problem as much as possible. In general it about loading PCL assemblies in Desktop application with Assembly.LoadFile(...).
Let's say there is a .NET 4.0 Console Application (called "C"). It references .NET 4.0 assembly (called "N4") and PCL assembly (called "PCL").
where N4 looks like this:
using System.Linq;
namespace N4
{
public class ClassInN4
{
public static string Greet()
{
return new string(
"hello from N4"
.ToCharArray()
.Select(char.ToUpper)
.ToArray()
);
}
}
}
PCL looks like this:
using System.Linq;
namespace PCL
{
public class ClassInPCL
{
public static string Greet()
{
return new string(
"hello from pcl"
.ToCharArray()
.Select(char.ToUpper)
.ToArray()
);
}
}
}
and C look like this:
using System;
using System.IO;
using System.Reflection;
using N4;
using PCL;
namespace C
{
internal class Program
{
private static void Main(string[] args)
{
Test();
Console.ReadLine();
}
private static void Test()
{
Test("N4", ClassInN4.Greet);
Test("PCL", ClassInPCL.Greet);
}
private static void Test(
string title,
Func<string> generator)
{
try
{
Console.WriteLine(
"{0}: {1}", title, generator());
}
catch (Exception e)
{
Console.WriteLine(
"{0}: {1} -> {2}", title, e.GetType(), e.Message);
}
}
}
}
When you run this application you get absolutely correct results:
N4: HELLO FROM N4
PCL: HELLO FROM PCL
Let's add AssemblyResolve event to CurrentDomain in Program.Main:
AppDomain.CurrentDomain.AssemblyResolve += (_, a) => {
var fileName = Path.GetFullPath(
new AssemblyName(a.Name).Name + ".data");
Console.WriteLine("Probing '{0}'", fileName);
return
File.Exists(fileName)
? Assembly.LoadFile(fileName)
: null;
};
So, what it does if assembly cannot be found it tries to load it from ".data" file.
Let's go application folder and rename "N4.dll" to "N4.data" and run "C.exe".
Probing 'C:\xxx\C\bin\Debug\N4.data'
N4: HELLO FROM N4
PCL: HELLO FROM PCL
So it goes through AssemblyResolve and finally loads "N4.data" and works as good as original.
Let's revert "N4.data" to "N4.dll" and rename "PCL.dll" to "PCL.data" and...
Probing 'C:\xxx\C\bin\Debug\PCL.data'
N4: HELLO FROM N4
Probing 'C:\xxx\C\bin\Debug\System.Core.data'
Probing 'C:\xxx\C\bin\Debug\System.Core.data'
Probing 'C:\xxx\C\bin\Debug\System.Core.data'
PCL: System.IO.FileNotFoundException -> Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes' or one of its dependencies. The system cannot find the file specified.
Please note that PCL assembly was loaded just fine, the problem is, it only can't find its dependencies (System.Core) anymore.
It's like Assembly.LoadFile(fileName) is-a no-no if loaded assembly is portable.
Did anyone have this problem? Did anyone solved this problem?
You can find all files here.
EDIT:
Thanks to leppie for forcing me to check other options. I actually wanted to be sure that I'm not lying while I answer "Yeah, yeah, I tried". Apparently it was worth checking.
From Suzanne Cook's .NET CLR Notes:
Be careful - these aren't the same thing.
LoadFrom() goes through Fusion and can be redirected to another assembly at a different path but with that same identity if one is already loaded in the LoadFrom context.
LoadFile() doesn't bind through Fusion at all - the loader just goes ahead and loads exactly* what the caller requested. It doesn't use either the Load or the LoadFrom context.
You can return the System.Core assembly of your platform (e.g. version 4.0.0.0 for .NET Framework 4.0) from the AssemblyResolve event, when asked for the 2.0.5.0 version.
I am loading all my referenced assemblies stored as resources via Load(byte[]), which also fails to resolve the 2.0.5.0 assembly, and I retrieve both System and System.Core from AppDomain.CurrentDomain.GetAssemblies().
I think you are getting these issues because:
You're getting an exception because you haven't got the latest .NET updates.
http://www.paraesthesia.com/archive/2013/01/21/using-portable-class-libraries-update-net-framework.aspx
Take note of the WSUS part - you may think you have the latest updates, but you don't cause your WSUS server is out of date.
This patch may help, but you're better just to get all the .net updates:
http://support.microsoft.com/kb/2468871
(from a comment above)
Try LoadFrom(...) rather than LoadFile(...) / Load(byte[]) and see if that fixes your issue? :)
I had the same problem and ended up with the following solution: invoke the following code before dynamically loading the PCL assembly.
Assembly.Load("System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes");
Assembly.Load("System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes");
If any other dependency is missing when you load your PCL assembly, you just need to add a line to code above.
For some strange and ununderstandable reason, it works.

Invoking remote methods is loading the remote assembly in parent appdomain

I think I've determined that even though I'm loading assemblies in a MarshalByRefObject in a new AppDomain that the assemblies are also getting loaded into the parent domain.
Here's my Assembly structure (arrows indicate dependency):
MainAssembly -> CommonInterfaceAssembly <- ExtensionAssembly
In the parent AppDomain I'm doing this:
var loader = (ExtensionLoader)extDomain.CreateInstanceAndUnwrap (Assembly.GetExecutingAssembly().FullName, "ExtensionLoader");
loader.loadExtensions (this);
and the Loader class is:
class ExtensionLoader : MarshalByRefObject
{
public List<IExtension> loadExtensions (ExtensionMgr mgr)
{
// Delegate to Addins to return the list of extensions
AddinManager.Initialize ();
AddinManager.Registry.Update ();
AddinManager.GetExtensionObjects<IExtension> ();
var extensions = new List<IExtension> (AddinManager.GetExtensionObjects<IExtension> ());
foreach (var ext in extensions) {
ext.Initialize (mgr);
}
return extensions;
}
}
I don't know if it's relevant to the question, but I am using Mono.Addins to load the extensions in the new AppDomain so I've left that code in. From what I can tell though things work fine up to the point where I invoke the Initialize method on each of the extensions.
So I have ran this scenario with the ExtensionAssembly in the same directory as the main executable and in a separate 'extensions' directory. What's curious to me is that when I invoke ext.Initialize either the ExtensionAssembly gets loaded in the parent AppDomain (if it exists in the same directory), or I get the below stack trace if not. Any ideas why?
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg, System.Exception& exc, System.Object[]& out_args) [0x001f0] in /home/tim/tmp/mono-2.10.8/mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs:247
Exception rethrown at [1]:
---> System.IO.FileNotFoundException: Could not load file or assembly 'Extensions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'Extensions, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
at System.AppDomain.Load (System.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) [0x00047] in /home/tim/tmp/mono-2.10.8/mcs/class/corlib/System/AppDomain.cs:785
at System.AppDomain.Load (System.String assemblyString) [0x00000] in /home/tim/tmp/mono-2.10.8/mcs/class/corlib/System/AppDomain.cs:762

Categories