how to edit a satellite assembly  
Author Message
singam





PostPosted: Common Language Runtime, how to edit a satellite assembly Top

hi,
i have created a satellite assembly for a culture "de-DE".
I ran the application with the culture setting of "de-DE" inside the application.
My application starts displaying all the text in german language.
Here i like to modify some german text without exiting from the current running application.Actually i tried to replace the satellite assembly ,in the folder /de-DE, with the modified satellite assembly
but it is showing some windows error message saying "cannot copy : it is being used by another person or program. close any programs that might be using the file and try again" .

My intension is to replace the old satellite assembly by the new one while the application is running.

Is it possible to do that

thanks,
Singam


.NET Development12  
 
 
Alex DeJarnatt - MSFT





PostPosted: Common Language Runtime, how to edit a satellite assembly Top

Moved thread from asp.net web services to Common Language Runtime (not sure this is the proper destination, but hopefully they can find the right place).

thanks

Alex



 
 
Brian Grunkemeyer - MSFT





PostPosted: Common Language Runtime, how to edit a satellite assembly Top

Sorry, for most apps, this isn't exactly a supported scenario, though it probably could be done if you're willing to do a ton of additional plumbing. I have one possible solution, then one more speculative one.

First, you could throw out the satellite assembly model and read .resources files directly. Note that ResourceManager.CreateFileBasedResourceManager may be useful for you here, though you might need to explicitly read every resource from the .resources file at once (bloating your working set) so that you can close the .resources file. You may have to create your own subclass of ResourceSet and/or ResourceReader to get the lifetime management done correctly. There's a lot of flexibility here, especially if you do not load satellite assemblies. I'm confident that something approximating what you want could be built here within a day or three.

Now for my more speculative approach that works with the existing satellite assembly model. I wouldn't recommend this approach for the faint of heart, or for anyone that hasn't read at least one good (Jeffrey Richter-caliber) book on CLR internals. There are three pieces you'd need to do:

1) Replace the file on disk

2) Convince the CLR to load the new satellite assembly

3) Tell the ResourceManager to reload resources

For #1, you can play some games with moving the old file to a temp location. This hacky solution that creates races if you're running multiple copies of your code simultaneously is pretty obvious.

For #3, the ResourceManager has a ReleaseAllResources() method that will flush all of its internal caches & close handles, etc.

For #2, here's where you run into problems. The CLR loader won't let you load an assembly then reload it with different bits, at least not within the same appdomain. You'd have to run the relevant part of your code within a second appdomain, unload that appdomain to unload the assembly, then create a third appdomain to run your code again. This of course gets into remoting, marshal-by-ref objects, potential loader context problems, etc. (Our Orcas AddIn Model will make some of this easier, but that's even more plumbing.) Also, it means multiple copies of your application running simultaneously on the same machine won't work reliably, unless you create a named mutex on the machine and acquire it the first time you look up a resource in every appdomain. If you're willing to live with a bunch of work, read on.

The only condolence I can offer is if you're recycling your appdomains, at least you don't have to worry about #3, since you'll be forced to allocate a new ResourceManager instance, and after you unload the appdomain (and explicitly trigger a GC & call GC.WaitForPendingFinalizers()!), then replacing the file on disk will also be easy. Here's a rough idea of how this might work, though honestly, I don't know if anyone has ever tried this (I certainly haven't):

AppDomain domain = AppDomain.CreateDomain(...); // Make one worker appdomain

Foo myAddIn = domain.Create(...); // Or use the Orcas AddIn Model

String s = myAddIn.Lookup(); // A cross-appdomain call to a method that uses the ResourceManager.

domain.Unload();

// AppDomain Unload is sort of asynchronous now - the work is now moved to the finalizer thread. Trigger a GC then block until the finalizers have completed.

GC.Collect();

GC.WaitForPendingFinalizers();

// Replace the satellite assembly on disk here! Also, should it be updated in the GAC

domain = AppDomain.CreateDomain(...); // Make a second worker appdomain.

myAddIn = domain.Create(...);

s = myAddIn.Lookup();

I wouldn't imagine that any devs coming after you would want to support this approach.

Brian Grunkemeyer

CLR Speculative Feature Theorizing Person