ubsicap / paratext_demo_plugins

Sample code to demonstrate how to create a Paratext plugin
2 stars 4 forks source link

Plugin DLL Woes #35

Closed GeoDirk closed 1 year ago

GeoDirk commented 1 year ago

After a long day of trial and error, I was able to finally figure out why our plugin wasn't loading in Paratext for a couple of users. Turns out that if users have on their system the SIL Converters 5.1 package, it conflicts with the loading of our plugin.

What do you need from me so that I can help you remedy this so that both the Converters and our package can be installed on the system as these folks need to have access to both?

GeoDirk commented 1 year ago

Fusion++ Log files attached 2023.08.16.17.26.08.4325.zip

jwickberg commented 1 year ago

I'm not sure exactly what to do about problems like this - even if we get SIL Converters changed, the problem could happen again when another plugin is installed.

The current plugin architecture has some advantages over the previous architecture we used, but now everything is running in one address space, so DLL conflicts are easier to happen.

Do you know the specific DLL that is causing the problem?

GeoDirk commented 1 year ago

@jwickberg On our end, our plugin fails on the line of code when we try to load the MediatR.Extensions.Microsoft.DependencyInjection extension. But if you look at the Fusion logs I posted above, there are early errors in loading important things like netstandard 2.0 and Microsoft.CSharp. Then towards the end where our plugin starts to load, it's erroring out on important DLLs like System.XmlSerializers before it gets to the MediatR one.

I can post our plugin somewhere for you if that is helpful.

jwickberg commented 1 year ago

We are working on the Paratext 9.4 beta, it's not quite ready for release yet, but I'm wondering if it will work better with both the SIL Encoding Converters and your plugin. We made some changes to what we include in Paratext and corrected some loading issues along the way.

If you can provide we with a version of the plugin I could install manually, I can try it with the beta. If I have to install it, I could probably the copy the plugin folder to the beta.

If you want to send the plugin to me directly, my email is: john_wickberg@sil.org

GeoDirk commented 1 year ago

ClearDashboardWebApiPlugin.zip

@jwickberg it is attached. Just drop in the \plugins directory

jwickberg commented 1 year ago

I'm getting this error: [2023-08-18T16:20:06-04, Thread=1] - Warning: ### Ignored error (Native libraries will fail): System.IO.FileLoadException: Could not load file or assembly 'file:///C:\Program Files\Paratext 9 Beta\plugins\ClearDashboardWebApiPlugin\ClearDashboard.WebApiParatextPlugin.ptxplg' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515) File name: 'file:///C:\Program Files\Paratext 9 Beta\plugins\ClearDashboardWebApiPlugin\ClearDashboard.WebApiParatextPlugin.ptxplg' ---> System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information. at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark) at System.Reflection.Assembly.LoadFrom(String assemblyFile) at Paratext.Base.Plugins.PluginManager.<>c__DisplayClass46_1.b__1() in F:\ParatextPatchBuilds\Paratext_9.4_Patches\ParatextBase\Plugins\PluginManager.cs:line 328 at PtxUtils.ErrorUtils.IgnoreErrors[T](String why, Func`1 function, Boolean logWarning) in F:\ParatextPatchBuilds\Paratext_9.4_Patches\PtxUtils\ErrorUtils.cs:line 118

Doesn't appear to be related to SIL Encoding Converters (I have 5.1 installed and copied the SIL EC plugin from 9.3 to the beta).

jwickberg commented 1 year ago

Just to verify that the error isn't caused by SIL EC, I deleted the Back Translation Helper plugin from the beta and still get the same error message in the log when starting Paratext.

GeoDirk commented 1 year ago

That looks like a Window's sandboxing issue related to downloading a zip file. There is a way to right click on a zip file and uncheck something to tell windows that the zip file is ok. Otherwise you get the above issue.

GeoDirk commented 1 year ago

Ah...found it. Do this to the zip file first:

  1. Right-click on the file and open Properties.

  2. Click on the Unblock button and then on Apply/OK.

Then extract it to your \plugins directory

jwickberg commented 1 year ago

Sorry about that - I took a short cut and copied straight out of the .zip file. I've run into the Blocked DLL problem before, but the error message never triggers what the problem is.

I now get this error from the plugin - no Back Translation plugin present: Server stack trace: at System.ThrowHelper.Throw(String paramName) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetServiceT at ClearDashboard.WebApiParatextPlugin.MainWindow.DoLoad(IProgressInfo progressInfo) in D:\Projects-GBI\ClearDashboard\src\ClearDashboard.WebApiParatextPlugin\MainWindow.cs:line 145 at Paratext.Base.Plugins.PluginWindow.FinalizeInitialLoad() in F:\ParatextPatchBuilds\Paratext_9.4_Patches\ParatextBase\Plugins\PluginWindow.cs:line 171 at Paratext.Base.ParatextWindows.ParatextWindow.<>c__DisplayClass128_0.g__LoadAction|0() in F:\ParatextPatchBuilds\Paratext_9.4_Patches\ParatextBase\ParatextWindows\ParatextWindow.cs:line 776 at PtxUtils.Progress.ProgressLauncher.RunAction() in F:\ParatextPatchBuilds\Paratext_9.4_Patches\PtxUtils\Progress\ProgressLauncher.cs:line 245 at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs) at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)

jwickberg commented 1 year ago

I'm at about the end of my day and will be on vacation next week. Maybe we can arrange a time on to work together when I get back.

GeoDirk commented 1 year ago

Yes that is where it dies on us in the code when the SIL Converter program is present.

Right now we just the two users with the problem uninstall the Converter when they want to run Dashboard and reinstall it when they need to transliterate. Not ideal but it does work.

Enjoy your time off!

tombogle commented 1 year ago

I wonder if maybe all we need is an added entry in the app config file for Paratext (though I'm not quite clear as to what library is causing the problem)? Reading between the lines, I'm wondering if you have a plugin that is dependent on another plugin? If so, then you should be aware that when Paratext loads plugins, it call Assembly.LoadFrom so that it can load a different version of a dependency if necessary. So if your plugin B relies on a library installed by plugin A but Paratext itself has loaded a different version of that library, plugin B would probably pick up the one previously loaded for Paratext not the one from plugin B. The other thing to consider is how you are detecting the presence of the Back Translation plugin. For example, if you are detecting its presence in memory at the time DoLoad is called on your plugin window, have you properly ensured that Back Translation plugin would have been loaded first? Of course if Back Translation plugin is not a Paratext plugin at all, then maybe I'm barking up the wrong tree.

jwickberg commented 1 year ago

@GeoDirk I'm back from vacation and caught up. Would you like to set a time to investigate this together? I'm in Eastern Time. Wednesday or Thursday afternoons are open this week.

GeoDirk commented 1 year ago

Yes please. Wed is open and Thursday afternoon is more limited. I'm also EST. Can you shoot a Zoom/Google Meet link to me

GeoDirk commented 1 year ago

@tombogle It's not what you are describing in this case. Our plugin is self contained and not dependent on another plugin. It is just the case when a user has the SIL Converters plugin installed, ours no longer loads and bails out trying to load the MediatR DLL.

Hopefully we can get this resolved without a big plugin architecture change on your end.

jwickberg commented 1 year ago

I believe this particular problem has been solved by the new version of the SIL Encoding Converters that is available on the project download page (https://software.sil.org/silconverters/#downloads)

The SIL EC folder had an older version of Microsoft.Extensions.DependencyInjection.Abstractions.dll that seemed to be the source of the problem, though I'm not entirely sure why this version of the file took precedence over the version in the ClearDashboardWebApiPlugin folder.

GeoDirk commented 1 year ago

We can close this issue now. I had a report back from a user who updated to the 5.2 version of the Converter and he said that both the plugin and refreshing the transliteration worked just fine together.