Page 1 of 1

FileNotFoundException on invoking method of another Plugin

PostPosted: Fri Feb 24, 2023 7:27 am
by sameermoin
Hi Everyone,

I have one supporting optional custom plugin for the Main custom plugin. The purpose of the optional plugin is to apply quick changes to the Main plugin's custom DLLs using the Jiwa code editor, I set the optional plugin execution order to less than the Main plugin but when I am trying to call a static method of the supporting plugin I am getting an exception:

"System.IO.FileNotFoundException: 'Could not load file or assembly 'OptionalConfigPlugin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.'"


I tried a couple of ways to make it work but both are not working.


Supporting Optional Plugin just contains a single class with some methods.
Code: Select all
namespace OptionalConfigPlugin {
      public class OptionalConfig{
                public static decimal OverrideInventoryPrice(JiwaFinancials.Jiwa.JiwaInventory.Inventory inventory, JiwaFinancials.Jiwa.JiwaApplication.Manager manager){
                          return 10;
                }
       }
}



calling the above plugin method in the Main plugin like below:

Code: Select all
bool isOptionalPluginExists = CheckCustomPluginExists(manager);
if(isOptionalPluginExists){
var assemblyName = "OptionalConfigPlugin.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
                var assemblies = AppDomain.CurrentDomain.GetAssemblies();
                var assembly = (from a in assemblies
                                where a.FullName == assemblyName
                                select a).SingleOrDefault();

if(assembly != null){
// calling method using assembly
}
}


In the above, I can't see the referred plugin (Optional Plugin) assembly in the assemblies variable.


On the second try, I directly called the class method.

Code: Select all
var price = OptionalConfigPlugin.OptionalConfig.OverrideInventoryPrice(inventory, manager);


Obviously, the above code will fail when the optional plugin is not referred but it is failing even though I referred the plugin.

How can I get the assembly of the referred plugin in the Main plugin?

Re: FileNotFoundException on invoking method of another Plug  Topic is solved

PostPosted: Fri Feb 24, 2023 8:42 am
by SBarnes
Without fully seeing what you are trying to do usually you need an assembly resolver which is like the code below, the first piece would either need to be the set up call of some plugin or possibly the application plugin but I don't think what you are trying to do is going to work because to call a static method in the plugin you are trying to change it is going to mean it needs to be compiled and loaded which means there will be a file lock imposed by windows, oh and by the way whilst the code editor compiles and checks the code that is NOT the compiling process that Jiwa uses at start up.

Without understanding what you are trying to achieve couldn't the same thing be achieved possibly by the use of delegates, perhaps it might be better if you outline the end goal of what you are trying to achieve.

Code: Select all
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, System.ResolveEventArgs args) { return AssemblyResolve(sender, args, Plugin); };   


and

Code: Select all
public System.Reflection.Assembly AssemblyResolve(object sender, System.ResolveEventArgs args, JiwaFinancials.Jiwa.JiwaApplication.Plugin.Plugin Plugin)
      {
//         System.Diagnostics.Debugger.Launch();
//         System.Diagnostics.Debugger.Break();
         // If the requested assembly is a reference to another plugin, then we need to attempt to resolve the assembly ourselves               
         foreach(JiwaApplication.Plugin.PluginReference pluginReference in Plugin.PluginReferenceCollection)
         {
            if (String.Format("{0}, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", pluginReference.Name) == args.Name)
               return System.Reflection.Assembly.LoadFile(pluginReference.Plugin.RuntimeFileName);
            
            if (String.Format("{0}, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", pluginReference.Name + ".dll") == args.Name)
               return System.Reflection.Assembly.LoadFile(pluginReference.Plugin.RuntimeFileName);
         }         
         return null;
      }      

Re: FileNotFoundException on invoking method of another Plug

PostPosted: Fri Feb 24, 2023 10:56 am
by Mike.Sheen
sameermoin wrote:In the above, I can't see the referred plugin (Optional Plugin) assembly in the assemblies variable.


Hmm... I would have thought it would be in the appdomain's loaded assemblies. If it isn't, then is there a chance it had trouble compiling or loading and as such was never loaded? Make sure the exception policy of your plugins hasn't accidentally been set to ignore, which would cause any problems of compiling or loading it to be silently ignored.

Also you can try the Manager.PluginCollection to see if your plugin is in there. If it is, you can get the location of the assembly from the plugin property RuntimeFileName and load and invoke that way.

Re: FileNotFoundException on invoking method of another Plug

PostPosted: Sat Feb 25, 2023 5:41 am
by sameermoin
thanks, Sbrane and Mike for helping. I found the referenced plugin in Appdomain