Only compile certain parts of my program depending on the calling assembly - c#

I have three assemblies. One assembly contains code that relies on the 'NETWORKING' COM service. This service is not available on some machines and I would like to only compile the code depending on the assembly that consume this assemblies.
I have two assemblies that rely on this shared assembly: One GUI and one CLI assembly.
I tried to use the #define preprocessor check, but this only works within the same assembly (right?).
The obvious yet time consuming choice would be to extract the code into a separate assembly.
I was wondering if there is another possibility. Just like defining symbols or something like. The CLI assembly would define the CLI keyword and the GUI assembly would define a keyword 'GUI'.
In the shared assembly I could then use something similiar to
#if CLI
using NETWORKLIST;
#endif
Is this somehow possible in Visual Studio / C#?

Assemblies are independent, so unless you're using the same "build" each time, the short answer would be "no, you can't do that". The most appropriate approach here is to move the relevant code to another assembly - which is probably less than 3 minutes work. Alternatively: just ignore it and accept that a few extra bytes of disk space are being used unnecessarily - it won't hurt.

Related

C# Adding a reference to a class in another project without referencing the project

I have two projects:
ProjectMain (class library)
LibraryProject (class library)
ProjectMain is a class library that should only be compiled as a singular library, no referenced libraries. I require a static class reference from LibraryProject BUT I don't want the LibraryProject assembly to be compiled together with the ProjectMain assembly.
I've tried 'link references' in visual studio but this is no solution as the library assembly is always compiled with the main assembly.
There are clear standard solutions to this issue but I am severely limited by the existing implementation requirements. Only one DLL can be compiled without any of the dependent assemblies being in the execution folder, GAC, private path, reflection etc.
The exact limitations are as follows:
Assembly executed in a sandbox from a third party provider, it only supports adding a single assembly with no direct references/reflection etc (it's horrible but my hands are tied)
We would like to handle the code organisation as best possible which means following standard best practices, unfortunately, due to the above limitation that's proving difficult.
What I would like to know is if there is a way to reference a class within another project without also compiling/using that referenced classes assembly. Possibly a method where the compiler 'embeds' the referenced class at compile time.
If your sandbox does not allow loading other dlls in AppDomain, load it yourself by embedding it. You can use Costura.Fody for this purpose, it is easy to use/install, just reference it from nuget.
Of course, embedding it in every scenario is madness and often comes with completely obscure bugs, which often solvable only by enabling traces in regedit.
So, in your case I would create two projects:
MyDll.csproj //it is my original project, with perfect code design and etc. Lovely.
MyDll.Sandbox.csproj //this one is the same as MyDll.csproj, except it is compiled with additional Costura.Fody reference, into single dll (every reference is put inside)
This way you just need to maintenance that MyDll and MyDll.Sandbox files are the same.

Approach to obfuscate an embedded dll in a WPF application

I have a WPF application whose output is a.exe. This application is dependent on an external b.dll (whose source code I have access to).
Requirements:
The output should only be a.exe which should contain the dll. I don't want to provide my users with a separate dll (if it can be avoided)
I should be able to obfuscate the code. (I don't want anyone to be able to modify it).
Approaches tried:
I embedded b.dll inside a.exe, it worked. But I was not able to obfuscate the exe as it gave an error that it was unable to find b.dll.
I obfuscated a.exe and b.dll but it did not work. It was unable to find b.dll.
Alternate approach :
Is there any way that I can perhaps add the spruce code of b.dll to my project and have the dll be compiled to the exe itself rather than a separate dll.
Is it possible to make this alternate approach work or are there any other ways ?
If nothing works, I know that I can compile a and b separately, obfuscate a and provide b as a separate file (what I'm trying to avoid).
Apologies for the formatting issues, if any, I'm using the android app. Let me know if you need any details.
I have had great success with Eazfuscator.Net in the past.
http://www.gapotchenko.com/eazfuscator.net
To run it from the command line enter the following command:
Eazfuscator.Net.exe -n a.exe b.dll
It will combine the two files into a single exe. The main program will be able to access the dll.
You can even set up Visual Studio so that the command line above runs as a post compile event.
Assembly embedding may seem quite confusing, so here is how it's usually done:
The dependencies are obfuscated if needed.
The target assembly is obfuscated. At this point, the obfuscator is also instructed to embed certain dependencies as a part of obfuscation process.
As a result, the embedded assemblies are stored as a resource of the target assembly.
In order to load dependencies at runtime, obfuscators usually install a handler for AppDomain.AssemblyResolve event that is raised by CLR when it fails to resolve an assembly automatically.
The handler extracts and loads an embedded assembly from the resource.
That's it. A good obfuscation tool allows achieving that quite easily. I don't see why it wouldn't work in the case with WPF application. If there are problems, I would recommend contacting product support.
Another option is assembly merging. Unlike embedded, the merged assemblies become an inseparable part of the target assembly code. For this reason, the assembly merging often helps to achieve a better obfuscation coverage and application startup time comparing to embedding. Although it may look a better option, merging may sometimes break the application functionality.

.NET building process and linking

Building is the sequence composed of compiling and linking.
In .NET the source code is compiled into the assembly that contains Common Intermediate Language and type info. At run time the JIT compiler converts the CIL code into native code.
I do not understand, in .NET ,how and when the linking is occurring.
Can someone please explain the process ?
Thanks in advance
There's no linking in terms of C++.
I mean, there's no any intermediate "obj"/"lib" files, that can be distributed and linked with another "obj" files later. Reference to an assembly always has dynamic behavior (always dynamic-link library), as opposed to C++ static linking.
Something like linking is a creation of .netmodule. You can build .NET source code with compiler into .netmodule instead of assembly (look here, especially section "Differences Between C# Compiler and C++ Compiler Output"), and later you can link these modules together into a single assembly (see al.exe).
But this is uncommon practice - most of assemblies contains single module, and this work (source -> module -> assembly) has been done by compiler (e.g., csc.exe) behind the scenes. Also, I can't remember any product being redistributed as a set of .netmodule (not as a set of assemblies).

Assembly with multiple managed modules

I understand that an Assembly is made of 1 or more modules, and resource files if any.
If you compile a project in C#, then the compiler will simply turn the code into a managed module, and then throw that module into an assembly. Now my question is, when would an Assembly have more than 1 managed module?
Heres a good explanation of that Netmodule vs. Assembly.
In short, one would use multiple modules for these reasons:
Multi-language assemblies.
If the assembly is consist of source files with different programming languages, you have to compile files with the same programming languages into netmodules, then link them into assemblies.
Separately maintained source files.
If the assembly is maintained by multiple developers, it may make sense to separate the source files into small collections. Each collection is owned by an individual developer. Collections are compiled as netmodules, then linked to the final assembly.
Small download footprint.
If the assembly is hosted in an http site, CLR will only download the main module at the first time. The remaining modules will be downloaded on demand. You can separate the less frequently used code from the main line code, and compiled the less frequently used code as a netmodule. User will only download the netmodule when it is needed.
Link the same source files into multiple assemblies.
You may have some common code that is used in multiple assemblies. The common code is small enough that it is not worth to compile them into a separate assembly. To avoid compiling the same source files multiple times, you can compile them into a netmodule, then link it into different assemblies.
If you have a class in a Project namespace, and another class in a Project.Utilities namespace, there would be two modules:
Project
Project.Utilities
This seems to be the way that the .Net assembly is organised, classes -> modules -> assembly.
The compiler seems to name modules by the namespaces the classes are in.
You can see the module structure in existing assemblies by using ildasm or .Net Reflector

Internalize Class and Methods in .NET Assembly

I have a set of multiple assemblies (one assembly is to be used as an API and it depends on other assemblies). I would like to merge all assemblies into one single assembly but prevent all assemblies except the API one to be visible from the outside.
I will then obfuscate this assembly with Xenocode. From what I have seen, it is impossible to internalize assembly with Xenocode.
I have seen ILMerge from Microsoft, but was unable to figure if it can do what I want.
http://research.microsoft.com/~mbarnett/ILMerge.aspx
I have used ILMerge from microsoft to internalize DLL's into a single assembled library. There is a useful GUI for using ILMerge called NuGenUnify. You can find it here.
I know Xenocode can merge assemblies into one but I am not sure if it will internalize other non-primary assemblies.
I have found the /internalize switch in ILMerge that "internalize" all assemblies except the primary one. Pretty useful!
I suggest you look at the InternalsVisibleTo attribute on MSDN.
You can mark everything in all the assemblies (except the API assembly) as internal instead of public, then reshow them to just your API assembly.
Having done that, using ILMerge should give you a single assembly with just the API classes visible.
There are some issues with ILMerge, but I think if you add optimisations + merge + obfuscation you're likely to create a highly complex situation for little benefit.
Why not have just one assembly, and make only your API public?
If you're always distributing them as a single assembly there's no reason not to just compile them as that. You'll get more benefit from compiler optimisations and it will be quicker to compile too.

Categories