Reputation: 460288
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
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
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
Reputation: 31630
Have you tried:
asmRule = Assembly.LoadFrom(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Rule.dll"));
Upvotes: 8
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