Tim Schmelter
Tim Schmelter

Reputation: 460288

Could not load file or assembly

This is my Errormessage:

Could not load file or assembly 'file:///C:\Windows\system32\Rule.dll'. The system cannot find the file specified.

The problem is that the same exe works in my development environment but not on productive server. The program is a tool that should run as a Scheduled Task on Windows Server 2008. It consists of an exe, one so called Database.dll and the Rule.dll. The exe should load the Rule.dll dynamically in codebehind but it fails with the above error only when started from Task Scheduler. Why is it looking in System32 folder and not in the Application folder? Is it an UAC-issue?

'Load the rule engine into memory
Dim asmRule As System.Reflection.Assembly = Nothing
Try
  asmRule = System.Reflection.Assembly.LoadFrom("Rule.dll") 'fails on productive system
Catch ex As System.Exception
  HistoryLog.writeLog("SysLog", ex, "Cannot find Rule.dll in Application Folder")
End Try

Upvotes: 4

Views: 8302

Answers (4)

P.Brian.Mackey
P.Brian.Mackey

Reputation: 44295

Check the production server's system32 folder for a file called Rule.dll. The "probing" or attempt to load the assembly from a system folder could occur before the attempt to load from the Application folder.

This is a listed disadvantage of LoadFrom in MSDN:

If an assembly is loaded with LoadFrom, and the probing path includes an assembly with the same identity but a different location, an InvalidCastException, MissingMethodException, or other unexpected behavior can occur.

If this is the case and you cannot remove Rule.dll from system32, then you can specify a full path to the assembly.

Upvotes: 2

Andras Zoltan
Andras Zoltan

Reputation: 42363

Set the task to 'Start In' the same folder as the exe (on Windows 7 this is on a property page on which you configure the path of the app to be run) - that way the current folder (from the environment) while the application is running is the same as the application folder. .Net should then use that folder when resolving non-rooted paths.

What you're seeing, I believe, is a common problem that you can also get with shortcuts.

That is - the startup folder is being set to the same as the root of the task scheduler - whose startup dll is in c:\windows\system32

The fact that 'it works on my machine(tm)' presumably is because when you debug it locally, you're running it directly?

The other answers here that suggest using BaseDirectory will also work.

Equally you could also change the code to using the full assembly name, and simply use Assembly.Load. However, this will break if the version/culture/publickeytoken of that DLL change in the future. Of course that could be mitigated by using a .config file to supply the name of the DLL to be loaded instead of hard-coding it. Which - in any case - is good practise.

Upvotes: 1

Ta01
Ta01

Reputation: 31630

Have you tried:

asmRule = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Rule.dll"));

Upvotes: 8

João Angelo
João Angelo

Reputation: 57718

The method LoadFrom will use Environment.CurrentDirectory to build the full path to the assembly that will be loaded. The current directory is not the same as the application base path.

You should provide the full path to LoadFrom method, you can build it using AppDomain.CurrentDomain.BaseDirectory if the file is located in the same folder then the executable.

Upvotes: 8

Related Questions