.NET: <codebase>

Apr 30, 2005
81
0
66
Hi,

I have a C++ (COM) server that loads a C# assembly via COM Interop. That assembly in turn is loading another assembly by name ( e.g. Assembly.Load( "someAssemblyName, 1.0.0.0" ); ). The assemblies exist in the same directory as the server and all works well.

What I would like to do is deploy an updated version of "someAssemblyName" at runtime. I have added a new <codebase> to "Server.exe.config" with @version = 1.0.0.1 and @href = file://some_full_path_to_v1.0.0.1_assembly.

This doesn't work as expected. No matter which version I pass to Assembly.Load(), the first <codebase> entry is the one that gets loaded. Once a version is loaded it is always returned, so changing the order in the .config file at runtime does not help. Any ideas?


- Pulling Hair


Additional Info:
1. These assemblies are private and therefore not installed to the GAC.
2. These assemblies are not strong-named. I tried strong-naming them which resulted in nothing being loaded and no useful exception information.




 

KB

Diamond Member
Nov 8, 1999
5,401
386
126
AFAIK the .exe.config file is loaded by the .Net runtime if the EXE is .Net based. It wouldn't be loaded for COM based EXEs. Are you able to access any .config settings from the COM EXE? You shouldn't be able to.
 
Apr 30, 2005
81
0
66
I couldn't find a definitive answer as to whether or not the config would be loaded in this scenario so I did the following:

1. Placed the assembly several subfolders down from the application base folder. .Net failed to find the DLL.
2. Created the .config file pointing to the correct path. .Net loaded the DLL.

Didn't try accessing any config settings as I assumed ( rightly or wrongly ) that .Net was indeed loading the .config.
 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
I'm confused by what it is you're saying for some reason. I can't tell whether you fixed the issue or not. Anyway, I'll clarify a few things:

app.config files are loaded by executables, not DLLs. It doesn't matter whether or not the executable is managed, so your COM server will cause the app.config to load when it communicates through interop ultimately asking the CLR to load the assembly in question. This is when your redirects and/or codebase hints will come into play.

The default probing path that the CLR uses to locate assemblies that it needs doesn't include 'n' subfolders from the application path. If you want this, you need to give it a hint as you have done (typically with a probing path being set in the app.config).

Finally, if you want to troubleshoot binding issues in the future, there are a few easy ways to do it to take out the guess work:

1) Enable Fusion logging. "Fusion" is the codename for the portion of the framework that facilitates binding. A little Googling should give you some articles on that subject.
2) My preferred method is to simply use a file system monitor. I like the one by Sys Internals (now Microsoft). It has the benefit of being easier to configure and load. Just log on errors for your particular application and you'll plainly see where it's failing.

Hope that helps a little, but I'm still not sure I'm answering your question.
 
Apr 30, 2005
81
0
66
The original problem of trying to load different versions [ simply a bump in the AssemblyVersion attribute ] of an assembly still remains. My second post was regarding the issue of whether or not the CLR would load the app.config when the host process isn't .NET. Your reponse backs up my tests on that subject.

I ran fuslogvw.exe and looked at the detailed log. Even though the assembly's DisplayName was "someAssembly, Version=1.0.0.1 (Partial)", it used the path from the 1.0.0.0 <codebase> to load "someAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null". Is <codebase> simply not the right mechanism for this? Or is it not even possible to load multiple versions of an assembly into the same process?

 

imported_Dhaval00

Senior member
Jul 23, 2004
573
0
0
Originally posted by: Descartes
app.config files are loaded by executables, not DLLs.

That is not correct. Best example: Add a Web reference to a Web Service in a DLL. Compile it and you'll see that a <assemblyname>.dll.config is generated which contains the URL to the Web Service used by the proxy.


Regarding the original problem: I have successfully used the <codeBase> technique in the past... but in my case, there was no COM InterOp. I have a feeling though that this should also work from within COM, too - after all, the DLL's execution context falls within the scope of the CLR process.

In any case, if you need to point your older apps to a newer version of an assembly, you'll also need to add the <bindingRedirect> element. Here is an example:

<?xml version="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft.com:asm.v1">

<!-- Optional probing element to help the CLR locate the assemblies in one of
application's subdirectories - in this case, the CLR probes the Testing and the
bin\Deeper sub directories -->
<probing privatePath="Testing;bin\Deeper" />

<dependentAssembly>

<!-- Assembly-related info -->
<assemblyIdentity name="MyAssembly"
publicKeyToken="1234567890123456" culture="neutral" />

<!-- When attempting to locate version 1.0.0.0 of MyAssembly,
load version 1.1.0.0 instead. -->
<bindingRedirect oldVersion="1.0.0.0" newVersion="1.1.0.0" />

</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
Originally posted by: Dhaval00
Originally posted by: Descartes
app.config files are loaded by executables, not DLLs.

That is not correct. Best example: Add a Web reference to a Web Service in a DLL. Compile it and you'll see that a <assemblyname>.dll.config is generated which contains the URL to the Web Service used by the proxy.

A web service is entirely different. Configuration files are per app domain, so that's what I meant by it being loaded (and thus referenced by) an executable. If the manifest of the executing assembly loads, then it will look for its app.config and that's it for the app domain.

A web service isn't loaded in the app domain of the consuming application, so it's perfectly acceptable to have different config files.

Things might have changed recently, but this is the way it was up to 3.0.
 

imported_Dhaval00

Senior member
Jul 23, 2004
573
0
0
Originally posted by: Descartes
Originally posted by: Dhaval00
Originally posted by: Descartes
app.config files are loaded by executables, not DLLs.

That is not correct. Best example: Add a Web reference to a Web Service in a DLL. Compile it and you'll see that a <assemblyname>.dll.config is generated which contains the URL to the Web Service used by the proxy.

A web service isn't loaded in the app domain of the consuming application, so it's perfectly acceptable to have different config files.

A WS can't be loaded because it is not a process - it is a means of communicating across boundaries. Your statement is not entirely true. You can have only one *.config file per app domain. Assume you have DLL1 with its app.config file. DLL1 references a Web Service called TestService. When DLL1 is compiled, .NET will generate DLL1.config which contains WS-specific settings for the proxy of TestService. Now assume you have a DLL2 which references DLL1. In order for DLL1 to work properly (when the WS is invoked), those WS settings in DLL1.config will have to be moved to DLL2.config (assuming DLL2 is the host). If DLL2 in turn is being referenced by an .exe, then the WS-specific settings in DLL1.config will have to be moved to the .exe.config file of the host. I hope this all makes sense - you can have only one app.config file per app domain, period.

To try and reassert this, create an ASP.NET Website. Add a reference to a DLL that in turn references a WS. You can try all your life, but any calls to the WS will fail until you move the WS-specific settings (copy-paste) from the config file of the DLL to the web.config file of the ASP.NET Website (by the way, the schema for a web.config and an app.config is the same).

Hope this didn't sound too confusing. On the contrary, I apologize if I misunderstood what you were trying to assert, Descartes.
 
Apr 30, 2005
81
0
66
Still trying to tackle this issue. Additional research on MSDN has revealed the following:

http://msdn2.microsoft.com/en-us/library/yx7xezcf.aspx states "no version checking for assemblies without strong names". This would explain why the <codebase> order affects which version gets loaded as it would ignore the version attribute and match the first entry.

http://msdn2.microsoft.com/en-us/library/aa98tba8.aspx states to the effect that assembies are cached by name. Does this mean that without a strong-name the assembly name is used ( which is obviously identical for both of my versions )?

Seems to me that I'll have to give the components strong-names ( which has always caused binding failures in the past ) and figure out the binding issues using fuslogvw. Is my understanding correct?

Cheers!
 

imported_Dhaval00

Senior member
Jul 23, 2004
573
0
0
(I could be wrong about this, because it has been a long time since I last used an assembly that was not strongly named) I remember forcing a bind to an upgraded version of an assembly, via an assembly that wasn't strongly named. You can try, and make sure fuslogvw is running... that way you'll know if the bind succeeds. In any case, if you can't, I would say give all your assemblies strong names. If you're using a third-party assembly, and this assembly is not strongly named, slap the third-party for deploying something that wasn't strongly named

I can think of another alternative: look at the AppDomain.AssemblyResolve event. Whenver the AppDomain is unable to load an assembly, this event is raised, allowing you to manually load the assembly from wherever (not restricted to private path). This also gives you a finer control of what is loaded in the AppDomain (your specific version). See if this helps. This event isn't discussed quite extensively, so it may be hard for you to find code samples online... maybe I'll post an example if you're interested in going down this path.
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |