Packing single assembly apps that have resources and some notes about the delay loader...

References:
[1]
I often get asked how one would ship a single assembly app that is in multiple assemblies...

If you haven't read my entry on packing assemblies into a single assembly for one file deployment, then you won't get much out of this posting.  So go back and read it if you haven't, refresh your memory by reading it again if you haven't read it in a while, and if you don't care about packing everything in one assembly, then move on to the next aggregated feed you've subscribed to ;-)

I got a question from a user today about using this technique for assemblies that had resources themselves and how this process would be resolved.  The user was concerned because the CLR was probing for culture specific resource libraries.  This is completely normal, but you never realize it until you hook the AssemblyResolve event.  I mean who would think that every time your app loaded, files that you never created, would actually be searched for.  Well it happens, and as you may have noticed a bunch of people get confused by it (read the common thread asking why loading a WinForms app over the web is so slow, while the probing logic of the app makes requests to the web server for files that don't even exist).

To point out, the delay runner can fully handle this situation.  In general, you'll have culture neutral resources in your own assembly.  Let the probing logic go ahead and fail out, and the your dynamically loaded assembly will become the resource provider just as would happen if you had run your assembly normally.  If you really wanted to pack all of your culture specific resources into a single assembly as well, you could easily get away with that, and simply use the techniques shown to read out those dll's and instantiate them as dynamic assemblies and return them from the resolver.

Personally, I never even saw this issue, since I wasn't using resources in my packaged apps.  I had always assumed that ResourceResolve would have been called instead of AssemblyResolve though.  Well, just goes to show that you never know.

As for the second note, I got some information that you might not even need a delay loader class.  I created a delay loader, because the types of applications I normally package aren't my own and I don't have the original source code.  However, if you do own the source code, it might be prudent to skip the use of the delay runner and instead embed the assembly resolving code right into the application you plan on packaging.  This has two side effects, first, you can't instantiate any types for dependent assemblies that are packaged as resources inside of the Main method.  If you do, the assemblies will be resolved and loaded before you get a chance to hook the AssemblyResolve event during the JIT process for the Main method.  If you move all of your normal Main logic into a separate function that you call after you've hooked the AssemblyResolve, then business as usual.  The second side effect is that you now have possibly two types of different resources in your executable.  The first type of resource will be embedded libraries, while the second type will be the actual resources used by your application.  The delay runner gets by this because the delay runner assembly ONLY contains embedded libraries and nothing more.

Anyway, figured I'd post these two useful snippets about single assembly packaging.  Enjoy!

Published Monday, June 14, 2004 4:42 PM by Justin Rogers

Comments

Monday, October 22, 2012 3:32 PM by seo资源

# re: Packing single assembly apps that have resources and some notes about the delay loader...

Wireshark works on the actual Apple pc while it can definitely pure excess just for this!