West Wind Internet and Client Tools
Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
Gravatar is a globally recognized avatar based on your email address. Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Steve Ellenoff
  All
  Jun 2, 2024 @ 03:50am

I had a project that was working just fine with wwDotNetBridge, but when I added Serilog Console and File Sink support to my custom .NET DLL, the error message is cannot load Serilog or one of it's dependancies.

Any idea how to resolve this?

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Steve Ellenoff
  Steve Ellenoff
  Jun 2, 2024 @ 04:04am

Small update. My DLL had a log call in the constructor of my class. I moved it out of there, and instead added it to a custom method GetDLLInfo() which returns info about the custom DLL version. So now I see an exception is thrown when the log function is called. No other information is provided.

Here is the .net logging class code

   public static class Logging
   {
       private const string template = "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{UniqueIdentifier}] {Message:lj}{NewLine}{Exception}";

       // Constructor
       static Logging() 
       {
           // Get machine specific info for logging
           var minfo = Environment.MachineName + "." + Environment.UserName;

           // Configure logging options
           Log.Logger = new LoggerConfiguration()
               .Enrich.FromLogContext()
               .Enrich.WithProperty("UniqueIdentifier", minfo)
               .WriteTo.Console(outputTemplate: template)
               .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day,outputTemplate: template)
               .CreateLogger();
           // Ensure we clean up serilog when the process that called the DLL is exiting
           AppDomain.CurrentDomain.ProcessExit += (s, e) => Log.CloseAndFlush();
           AppDomain.CurrentDomain.DomainUnload += (s, e) => Log.CloseAndFlush();
       }
       // Log a message
       public static void LogMsg(string msg)
       {
           Log.Logger.Information(msg);
       }
       // Log an exception
       public static void LogException(string msg)
       {
           Log.Logger.Error(msg);
       }
   }
Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Rick Strahl
  Steve Ellenoff
  Jun 2, 2024 @ 05:10pm

Wrap an exception handler around that code and set an error message, or step through that code with the VS debugger (set debugging to your VFP executable, then start debugging, VFP opens (or your app) and you can step into the code).

Most likely culprit is that the assemblies are not accessible or the logger is not initialized. That code looks like it might be expecting Dependency injection and the logger likely is null. At minimum you should check for that or make sure your constructor sets the logger.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Steve Ellenoff
  Rick Strahl
  Jun 3, 2024 @ 11:55am

Thanks for the suggestions Rick. I stepped through the code, it never get's to the constructor of the Logger class. Instead it throws the exception on the code that is calling the log function. The exception is exactly the same as what is showed in my first post, which basically says the serilog.dll is not able to be loaded.

I currently set a path in VFP to where my .NET project's Debug\bin directory holds all the .dll files needed. For testing I copied all those into the folder where I run the vfp test.prg I built.

So if I disable both sinks in the serilog setup code, vfp works fine. If I enable either console or file sink, I get the same exception. So clearly it can't load either of those, but I'm unsure why.

Questions

  1. Why must I copy all the dll files into my current folder for the test.prg rather than rely on vfp finding the path as it does when I am not using serilog. Is that a bug or limitation of wwDotNetBridge? I'm using latest from github.
  2. How can I determine why the sink .dll files are not loading?

Thanks again for your advice.

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Rick Strahl
  Steve Ellenoff
  Jun 3, 2024 @ 12:30pm

Yeah that's because the code JIT compiles. The reference is not loaded until your code tries to run code in that method and then it has to resolve the logger. If it fails before code runs in the method but on that method the most likely culprit is missing dependencies. Whatever components you're using make sure all the assemblies can be found in your application path. You may need more than just the dependencies directly referenced. For example, Serilog references a bunch of Microsoft dependencies and you may need those.

Easiest way to figure out what you need is create a .NET project add the Nuget package for your component and see what ends up in the bin folder besides your main executable.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Rick Strahl
  Steve Ellenoff
  Jun 3, 2024 @ 01:00pm

Specifically you'll need all of this (for net472):

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Steve Ellenoff
  Rick Strahl
  Jun 3, 2024 @ 04:55pm

Hi Rick- Yes, I had already placed everything in my .net project's debug\bin folder (i mean everything just to be sure) into my vfp folder before your last response. It is still unable to load. Scratching my head at this point. -Steve

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Rick Strahl
  Steve Ellenoff
  Jun 3, 2024 @ 05:39pm

Right framework? You're not mixing .NET Framework and .NET Core Assemblies?

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Steve Ellenoff
  Rick Strahl
  Jun 4, 2024 @ 06:57am

Don't think so. The .NET project is targeting 4.8, and I simply used NuGet to install Serilog. It works fine when running from .NET. I then simply copied all files in the Debug\bin folder to my VFP folder and run my test.prg.

Gravatar is a globally recognized avatar based on your email address. re: Failure to load Serilog in .NET Framework 4.8 using wwDotNetBridge
  Rick Strahl
  Steve Ellenoff
  Jun 5, 2024 @ 11:41am

One thing comes to mind is that Serilog may just not be configured or in scope. You mentioned you originally called from the constructor, but there was no setup code? I don't remember off hand how the logger works since in a .NET app you usually inject it via Dependency injection but you can't do that in your FoxPro app (unless you manually set it up in your .NET code with custom services collection and a DI container).

© 1996-2024