Controlling when to Initialize LibZ ie resolve assemblies when application starts up

Feb 20, 2014 at 10:59 AM
Thanks for super work!

I have injected a bunch of dlls directly into the main assembly with your command-line tool and that works for most dlls, but not having some of them outside makes the application crash, because these dlls are used very early on in my static void main of the application and it seems that libz is not initialized at that point yet..

I looked at the LibZ-injected application and it seems to me that LibZ is initialized in the <Module> static constructor like so:
static <Module>()
{
    LibZInitializer.Initialize();
}
im not really familiar with IL so im not sure how you injected that Module in there, but my guess is that this static cctr is called after my static void main, which is the reason libz is not ready early enough? http://stackoverflow.com/questions/9398509/how-does-a-static-constructor-work

is there any way for me to initialize LibZ first thing in my static void main? what could i call?
or is the issue elsewhere?

ta!
Coordinator
Feb 20, 2014 at 11:29 AM
Module initializer (static <Module>) should be first thing .NET executes but I do in fact use some tricks to inject it (as you don't have access to it from C#).
Without some example I can work on (just try to model same thing with some simple assemblies) I can't really say much.

What I would do RIGHT NOW (if you need it working RIGHT NOW). Is to create fake mini-exe which actually references your .exe and in its own Program.Main just calls the other one's Program.Main passing all args and inject everything into this fake-mini-exe. You get clean slate.

Did you use embedded LibZ container (Scenario 4) or straight assembly injection (Scenario 1)?
When I refer to scenario I mean scenarios from: https://libz.codeplex.com/wikipage?title=Usage%20scenarios&referringTitle=Documentation
Feb 20, 2014 at 12:55 PM
Edited Feb 20, 2014 at 12:58 PM
thanks for the reply!

i did a plain test project and indeed the issue is not there. so i realized i did not describe when the issue happens exactly enough, the module initializer does not seem to be called when you are trying to install your exe which is a windows service, the command line to do that woudl be smth like:

C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil /i C:\smth\MyLibZededService.exe

InstallUtil must be running the exe in an unusual way, such that the module initializer does not get called.. not sure what to do about this at all? it suggests that libz does not work with windows services? one way to work around it would be to allow me to call the LibZInitializer.Initialize(); from my static void main somehow?

p.s. howto on installing services
http://msdn.microsoft.com/en-us/library/sd8zc8ha%28v=vs.110%29.aspx
Coordinator
Feb 20, 2014 at 1:30 PM
And yet again. I never tried. But remember you can ALWAYS use "Scenario 6" (note: no instrumentation). Include LibZResolver.cs source in your project, create another static class with entry point, initialize LibZ and pass control to your current entry class after that. It should work.
Feb 20, 2014 at 3:23 PM
Im not sure how to use LibZResolver given i have been using Scenario 1 and i dont have any .libz container files.
Can i use LibZResolver to initialize dependencies embedded with libz inject-dll ... ? i.e. back to just calling LibZInitializer.Initialize() :)

thanks again!
Coordinator
Feb 21, 2014 at 10:50 AM
I did try with windows service and it works fine. The problem is YOUR static initialization somehow is getting executed before LibZ initialization. Move initialized static a little bit "down" and it will be fine.

Send me a skeleton of windows service you want to test, and I can show you on real example.
Coordinator
Mar 11, 2014 at 3:54 PM
Edited Mar 11, 2014 at 3:55 PM
I think now that I might have been using this in slightly different way than you did.

So let me describe. I wrote something you might call WindowsServiceImpl. A class which does the job and inserted it into assembly "MyServiceImpl.dll". Then I created SEPARATE service library MyService.exe. This MyService.exe DOES NOT have ANY references to non-framework assemblies apart from MyServiceImpl.dll.

MyService.exe has an MyInstaller class and MyService class (which is just a facade). MyService.OnStart just calls MySeriviceImpl.OnStart, MyService.OnStop just calls MyServiceImpl.OnStop, and so on. Then I LibZ'ed all .dlls into MyServiceImpl.dll.
So you end up with 2 assemblies:
  • MyService.exe - clean from external references, an installer class and facade class which is redirecting all calls to MyServiceImpl.dll
  • MyServiceImpl.dll - doing all the job, and LibZ'ed with all external assemblies
Microsoft's InstallUtil tries to scan the whole service .exe for installers. So if you had classes doing fancy stuff inside your .exe it was failing as it could not find assemblies it needed (actually, it didn't need them but it didn't know that).

And "yes" (if you ask). You need two assemblies to properly handle service. One "clean" facade for install and other one to do the job.

NOT TESTED: Other solution would be to use "TopShelf" as a host. It is not installed with InstallUtil it just can install itself. At least AFAIU.
Mar 14, 2014 at 10:43 AM
thanks! i will use your suggestion to use a clean .exe;
btw, when i tried to install a completely new empty service with some LibZeded references it worked with InstallUtil as well, so it is something with my production service that is different, and it is too much work to find out what, but it might be because it is using PostSharp, which does some embedding as well.. i will use the clean .exe suggestion though :)