Thursday, April 5, 2018

C#.Net Static Linking Adventures

My app uses two DLLs - say Lib1 and Lib2 from a CommonDll folder.

With normal linking these DLL's also need to be placed with App executable. But previously we have been providing only App exe only.
Hence to keep the compatibility and to lessen deployment headaches, the above 2 DLLs will be statically linked in the executable.

In .Net world this not so straightforward as setting a static linking flag in linker.

Here we need to provide following steps. I have added the rationale for each step alongwith.

1. Add the DLL's to project as resources - preferably in a Resources folder. Go into these DLLs properties and change "Build Action" from "Content" to "Embedded Resource". Now the DLLs shall get embedded in the exe.

2. Provide a handler for AssemblyResolve event. This new handler looks for assemblies in Resources and if found, loads them there.
This handler is like below:

private static Assembly ResolveEventHandler(Object sender, ResolveEventArgs args)
    String dllName = new AssemblyName(args.Name).Name + ".dll";
    var assem = Assembly.GetExecutingAssembly();
    String resourceName = assem.GetManifestResourceNames().FirstOrDefault(rn => rn.EndsWith(dllName));
    if (resourceName == null) return null; // Not found, maybe another handler will find it
    using (var stream = assem.GetManifestResourceStream(resourceName))
        Byte[] assemblyData = new Byte[stream.Length];
        stream.Read(assemblyData, 0, assemblyData.Length);
        return Assembly.Load(assemblyData);

To add this to your program add first line as:
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler( ResolveEventHandler);

3. Add a preBuild step where you will copy the latest DLLs from CommonDll folder to your Resources folder.
For this go to Project Properties > Build Events > Pre-Build Event Command Line

call "$(DevEnvDir)..\Tools\vsvars32.bat"
copy "$(SolutionDir)CommonDll\Lib1.dll" "$(ProjectDir)Resources"
copy "$(SolutionDir)CommonDll\Lib2.dll" "$(ProjectDir)Resources"

This ensures you have latest version of assemblies. Incidently we have been putting all solution dependent lib assemblies in CommonDll folder.

4. Above three steps are not sufficient because of the nature of loading of assemblies. CLR tries to load all dependent assemblies at start of function. So with normal main code with the handler override at start, won't work. Because CLR would be looking for dependent assemblies at start of Main and before executing our AssemblyResolve handler registration.

To handle this - in main() provide two functions:
void Main()

void Initialise()
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler( ResolveEventHandler);


Void RealMain()
    // Your actual Main code here

This way the assembly hander is registered before any assembly calls are made.

5. Now when you build the project you will find the Lib1 and Lib2 dll's in bin/Debug folder. But we don't want them here, dont we? Ok. To fix this - go to References - Right Click on Lib1 > click on Properties. Here change "Copy Local" to "False". Also make the same change for Lib2. Now delete the dll's from bin/Debug and rebuild the project. Now you will find only App exe there.

This way we are providing single App exe with all common code from Lib1 and Lib2 dlls.

Tuesday, April 3, 2018

ROM adventures on Nubia Z9 mini

Remember this one I gave to my Sis last year... Well since last month it started giving problems. What happened was the phone would get stuck in starting apps phase and zombie out. Only way to bring it back from zombie mode is to factory reset from recovery. But after a few days, some things related to Google Play Services would update and the phone would zombie out again. Sister got fed up and gave me the phone to fix.
So I went through a number of hoops to fix this issue and it's still not fixed.
To start with, the phone ran Mokee ROM v6.0 - marshmallow based with open gapps. Now all this is about two years old - things from 2016. And it all worked fine for last two years.
So what I did was reflashed everything and tried to see what's wrong. Worked fine till play services are updated. as soon as play services are updated, phone zombies out.
Ok. Get new version of gApps. Got it but after clean flashing that too, no change. Same issue. So maybe the Rom is gone.
So I download latest version of mokee marshmallow release Rom. Clean flash that with latest gapps. Phone works fine for a while but then craps out after installing gmail etc.
Ok. Can I revert to stock rom? Downloaded a version from Nubia website - turns out its real pain in the ass trying to install it. It needed latest recovery. And after installing that I found out the file I downloaded was corrupted. unfortunately nubia website does not provide checksums or anything. So got to hunt forums for stock rom download.
So after some more search got hold of couple of stock roms. The people on xda did say that these roms are installable with twrp But found out that's not the case. There's a twrp 3 version present. But I'm really fed up of going through the hoops.
So going to try Mokee 5.1.1 with compatible gapps. If it works, then will stick with it.
Some time later......
Pulling hairs.... Did not work! Seemed to work. Gmail worked, GMaps worked, but as soon as I installed whatsapp, it zombied out again with crashes all around! Not even settings would work!
Anyway, so trying a different approach now. Got couple of good zips of official update. The guys say I have to get stock recovery and on of these good images would work fine.
I don't have one click recovery tool here on this laptop and I can't install it since I don't have admin access. So I googled if one can use TWRP to flash stock recovery. Google says yes. So doing that I got to Stock recovery. Now I'm trying the stockest stock firmware that I have downloaded from Nubia official website.
The recovery has accepted this image too. Lets see if it works or not! Fingers crossed!
Some more time later...
Okay! Flashing successful! Lets see if it loads and is stable!
Hmm what's this? Stuck at Be yourself for like 10 mins. Google google. Hmmm, it's okay - phone is optimizing apps. Okay!
Some more time later...
Hmm phone is alive with Nubia UI 4 and Android Lollypop. Feels smoother too! Lollypop is definitely lighter than Marshmallow! By this logic Android Z will need a a supercomputer! Huh, logged in to google, connected WiFi, installed whatsapp - no dreaded app stopped dialogs yet!
Lets update all google apps and see. Looks okay. nd in Accounts section there's a button to remove google account too!! Cool!!! Alright then, my experiment is successful!!!

Thursday, March 15, 2018

.Net Solutions, DLL's, Build orders etc

Got to learn some new thinigs about Visual Studio today. Basically I wanted to build a library and integrate it into an existing solution. 
Steps: 1. Open Solution, Add new project of type "Class Library". Then create namespaces, classes, static library functions etc. Build it. Build OK, DLL ready.
Step 2: In other project ( where DLL is to be used), Add reference, Browse, Select Newly created DLL. Add using for DLL namespace. Call function in DLL. Call OK. Build this project. 
Hiccup! Issue no 1: DLL project was using newer .Net version while other project (Lets say App project) was using slightly older version and so it's build was giving error - Type or namespace for Library namespace not found. 
Bit of googling gave me solution. So set Lib's .Net version to same as App. Build OK. 
Next step: Verify solution is building correctly. For this there's something called build order to consider. For this in VS there's a setting - "Project Build Order...". This can be reached after right clicking on Solution in Solution Explorer. 
This opens a small dialog box where you can setup project dependencies and with correct dependencies appropriate build order is prepared. Here I set the app project to be dependent on Lib and the build order was updated accordingly. Voilla! 
So I rebuilt the solution and it all worked out great! 
Feels good when things work without much fuss!!!