Search code examples
c#entity-frameworkt-sqlsql-server-expresswindows-server-2012

Exception Thrown: 'System.IO.FileNotFoundException' in C# Windows Service When Entity Data Model Object Instantiated


Running on Windows Server 2012 R2 Standard is a C# Windows Service (.Net Framework 4.7.2) using Entity Framework that I wrote which reads data from a file and passes the data to a local SQLExpress (2016) stored procedure to insert the data into the DB.

While testing on my Windows 10 machine it works fine, but after moving the executable and exe.config to the Windows Server and updating the config with the correct DB information in the connection string, the Event Viewer shows the following Windows Application Error:

Source: .NET Runtime Event 1026

Application: Print_Mail-DBAuger.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
   at Print_Mail_DBAuger.Program.StartParseAndInsert(System.String, System.Diagnostics.EventLog)
   at Print_Mail_DBAuger.FetchService.OnChanged(System.Object, System.IO.FileSystemEventArgs)
   at System.IO.FileSystemWatcher.OnCreated(System.IO.FileSystemEventArgs)
   at System.IO.FileSystemWatcher.NotifyFileSystemEventArgs(Int32, System.String)
   at System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32, UInt32, System.Threading.NativeOverlapped*)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)

This seems to be preventing the stored procedure from being called, so no data is being passed to the DB.

I have narrowed the issue down to the instantiation of the Entity Data Model object:

PrintMailEntities dataEntities = new PrintMailEntities();

This line calls auto-generated code created by the Entity Framework:

public partial class PrintMailEntities : DbContext
    {
        public PrintMailEntities()
            : base("name=PrintMailEntities")
        {
        }
        
        // Several more auto-generated methods...
    }

And the super class constructor (again, part of the Entity Framework, not my code):

public class DbContext : IDisposable, IObjectContextAdapter
    {
        //
        // Summary:
        //     Constructs a new context instance using the given string as the name or connection
        //     string for the database to which a connection will be made. See the class remarks
        //     for how this is used to create a connection.
        //
        // Parameters:
        //   nameOrConnectionString:
        //     Either the database name or a connection string.
        [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
        [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public DbContext(string nameOrConnectionString);

        // Other overrloaded constructors not used...
     }

Everything in the program prior to this line works as desired (I used several application event logs to track what was happening since I don't have Visual Studio on the Windows Server to debug with.) The file I am trying to read from is not the issue, I can read that information fine.

I have also tried surrounding the instantiation with a try/catch to catch the FileNotFoundException, but the catch is never fired. I have also mirrored the database permissions of the Windows Server DB to match that of my local machines DB, and running both with admin privileges.

Here is the connection string in the Windows Server exe.config:

<connectionStrings>
        <add name="PrintMailEntities" connectionString="metadata=res://*/DataModel.csdl|res://*/DataModel.ssdl|res://*/DataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=machineName\HPWJA;initial catalog=PrintMail;integrated security=True;multipleactiveresultsets=True;application name=EntityFramework&quot;" providerName="System.Data.EntityClient" />
    </connectionStrings>

Again, this works fine on Windows 10 with the connection string pointed to a DB that mirrors the Windows Server DB. There are no build errors on my machine, and there are no SQL Server Logs on the Windows Server stating that anything wrong is happening on the DB side.

EDIT

Thanks to RB I now have more details about this "file" that couldn't be found. Here is the updated event log.

Error: Could not load file or assembly 'EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
   at Print_Mail_DBAuger.Program.StartParseAndInsert(String inputFile, EventLog programEventLog)
   at Print_Mail_DBAuger.FetchService.OnChanged(Object sender, FileSystemEventArgs e)
EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 was missing.

The error seems to be referencing a section element in app.config

<configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>

The server does not have internet, so maybe it's trying to pull the nuget package from online?


Solution

  • The issue was that I was missing the EntityFramework.dll found in the Release directory of the build output. Adding both EntityFramework.dll and EntityFramework.SqlServer.dll solved this issue. Thanks RB for helping me find this.