C# Class Library How To Add Startup Code [duplicate] - c#

This question already has answers here:
C# equivalent of DllMain in C (WinAPI)
(4 answers)
Closed 8 years ago.
Below is how to write C++ functionality to do something when the DLL is first called on the server. How does one do this in C# Class Library? The Startup in properties is grayed (disabled) for Class Library project out in Visual Studio but need to be library as I'm using it in my web application as reference. And not sure how to write an equivalent in C# so I could do some code to log events when the dll is loaded or started.
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Here is where the module POST should be invoked
// Return FALSE to fail DLL load in case POST fails
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}

I'm using it in my web application as reference
If it's hosted in IIS you can use PreApplicationStartMethodAttribute to run code very early on in your application startup.
This allows you to perform once-off initialisation but might force the initialisation earlier than necessary, because IIS will run your code as the application starts up rather than the first time you use classes in the assembly.
how to write an equivalent in C# so I could do some code to log events when the dll is loaded or started.
DllMain has some pretty severe restrictions. You can't expect to be able to log events reliably from DllMain anyway, so there's no precedent for "I can do it like this in C++ now how do I do it in C#".

There is no such construct in C#. C# is an object-oriented language, so all* executable code resides in classes. The CLR supports such an initialization, but it is not available in C# or VB.NET.
ASP.NET does support attributes that can be added to assemblies to execute code on startup, but it's specific to ASP.NET; it does not get executed when you load the assembly into a WPF app, for example.
However, that also means that you do not need library initialization code in C#. If you have code that needs to be run before classes in the assembly are used, then use the static or instance constructors of those classes to initialize appropriately.
If you have expensive code that is not appropriate to run in a constructor, my next choice would be a documented Init method where you allow the user to choose when to run initialize code. If the user chooses not to run it at startup (or does not know to, then run it when the initialization is required (constructor, member access, etc.)
* I would expect that are some esoteric exceptions, but none that I can think of

I'm not sure if this is the best approach, but you could use a static constructor, for example:
public static class Class1
{
static Class1()
{
//this constructor will be called the first time this class is used.
}
}
Note, that this constructor would not be called until the first time any of the static members of the DLL are used, which is why this may not be the best approach. However, you could, of course, take care of any instance-based initiation in an instance constructor.

Related

Using the same dll in another dll and a third codebase that runs the executable

So basically I am creating my own dll for use in a c# codebase, using c++ and a c-style layer for exporting functions. The issue is that both the c# part of the code (which actually runs and uses the dll) and my library itself both use another library (it's imgui, so lets call it such, even though it is irrelevant mostly) that runs on global state.
I initialize imgui to certain settings in my own dll and then use some of its functions in the c# code. Currently I am simply compiling the library into my dll and doing a c# binding myself that issues calls to imgui through my own dll. My question is whether I can use imgui as a dll for use both in my own dll and the main c# program in such a way that state is shared and the initialization step initializes the same code for both my own dll and the c# code.
That is, the c# code calls one of my functions in my own dll to initialize it, that function imports a dll (imgui), in the common directory for both my dll and the executable, and initializes IT. After this, the main c# program that imports both my dll and imgui then calls imgui functions to manipulate it's state. Will my dll and the main c# program be manipulating the same imgui state?
Generally yes
I say 'generally' because there are some conditions:
Everything needs to be in the same process (you are not clear on this but I assume so)
Both callers need to be able to get some handle on the state. So for example, if the state is memory allocated on the heap, then both callers need to be able to get a pointer to it, or else it needs to be a global variable somewhere they can access, either directly or indirectly.
Really it is the same as if it was 3 different C# modules
(also adding the disclaimer to think if you really need to use the C++, but I'm sure you have your reasons)

C# DLL Injection - Call Method of Running Application

Lets say I have an executable 'foobar.exe' written in C# and now compiled, running on a Windows box. One of the functions in the application is the following (example):
public static async Task LoadBox(string msg)
{
System.Windows.Forms.MessageBox.Show(msg);
}
I would like to write a DLL in C# that calls this method in the application. The DLL, say 'injected.dll', will be injected into the running 'foobar.exe' process using the injector referenced here: http://www.codingvision.net/miscellaneous/c-inject-a-dll-into-a-process-w-createremotethread
Is it possible from the newly injected DLL to call the public function in the original exe? If so, any example code in C# would be appreciated.
My approach would be to use the concepts of Reflection. We could make the EXE load an assembly through reflection, discover a Type and invoke a method on this Type and then pass an instance of a class in your EXE to this method, which in turn does a call back. A round about way - but it would work.
You can use the method System.Reflection.Assembly.LoadFrom( to load an assembly compiled for .NET. This is a fairly old technique, nothing new about it. Dependency contains and applications that are meant to load plugins post deployment are written using this method.
Step 1
Load the plugin assembly into the current Appdomain using System.Reflection.LoadFrom
Step 2
Find the Type in this plugin assembly by using Assembly.GetTypes()
Step 3
Pass an instance of a class defined in your EXE into the plugin and have the plugin do a call back. This is what an event call back would actually do.
Link
https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance?view=netframework-4.7.2#System_Activator_CreateInstance_System_AppDomain_System_String_System_String_System_Boolean_System_Reflection_BindingFlags_System_Reflection_Binder_System_Object___System_Globalization_CultureInfo_System_Object___

How do I detect if the application type is WinForms or Console? [duplicate]

Is there a simple way to have a code library automatically detect if it's being called from a console application or a windows application? I'd like my library not to report to the Windows Event log if it's being called from a console window, but instead report to the console window. If however, it's not being run from within a console window, it should report to the Windows Event Log.
I thought about requiring my the logging component to be passed the log target, but it would be neat if it could just automatically handle these two targets natively. I don't yet require something as extensive as log4net, indeed, if it becomes necessary to provide support to log to a database/file and other as yet unknown logging targets, then I may recommend such a solution. For now though, just having my component auto-detect the environment and log to the console or the event log according to the environment would be plenty.
Just discovered that "Console.Title" will be a blank string in a windows application and it will be automatically set in a console application.
Still a hack though.
Architecturally, passing the logging context into the library component is the right choice. The library doesn't, and indeed shouldn't, know that much context about the environment it's being run in.
Because you want to support these two special cases natively within the library, I'd suggest a unified approach.
Go ahead and create the more generalized logging entry point/knob that the caller controls.
Create a separate entry point/knob that automatically sets the generalized one for the cases that you want to automatically support.
Even that seems too complicated based on your description, though. Have you considered simply using appropriate TraceListeners in your Diagnostics collection, where your console app adds the appropriate TraceListener to output to the console and the non-console app adds the appropriate EventLog TraceListener to output to the Windows event log? This has the added advantage of working well with all the built-in .net logging support without assuming any external dependencies (e.g., log4net).
Variants of this question have been asked before. Namely here and here.
'
The solutions seem to boil down to two options
Using reflection to figure out what
is calling you.
In the case of console application
put a call to console in a try-catch
block and see if it fails or
succeeds.
My own recommendation is to have your library export an interface. The interface has a function or property that return the type of the caller. The calling object has a class that implements the interface and return what type it is. Because complexity is a concern you can control that somewhat by what you place in the interface.
If a application doesn't register itself with the library then you can try throwing an error or trying some scheme of automatic detection.
By using an interface and throwing an error you are making it explicit to the programmer using the library what exactly you expect. The interaction between the two is defined by the interface.
In addition the interaction is more flexible than a automatic scheme because I, as the user, get to choose how my calling binary interacts with your library rather than some mysterious set of rules.
I know it's kind of a hack, but calling Console.Read will throw an exception when there's no console.
bool isConsole = true;
try
{
isconsole = Console.CursorLeft >= int.MinValue;
}
catch( IOException )
{
// Try to attach to parent process's console window
isConsole = AttachConsole( 0xFFFFFFFF );
}
...
[DllImport( "kernel32", SetLastError = true )]
private static extern bool AttachConsole( uint dwProcessId );
It's a side effect so it may not be a reliable method of detection, but it works for now.

SecurityException: ECall methods must be packaged into a system module

I have a (C#) function similar to the following.
private static bool SpecialCase = false;
public void Foo()
{
if (SpecialCase)
{
InternalMethod();
return;
}
Console.WriteLine();
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void InternalMethod();
When I execute this with the .NET Framework 4 inside the debugger, the method successfully prints blank line to the console and returns. When I execute it outside the debugger, it throws an exception with the following message:
System.Security.SecurityException: ECall methods must be packaged into a system module.
It appears the exception is thrown when the JIT compiler compiles the method as opposed to when (if) InternalMethod is called. Is there anything I can do (e.g. attributes) to tell the CLI to either not throw the SecurityException, or delay the exception until the method is actually called?
Side note on the use case: The SpecialCase field is effectively false when running with Microsoft .NET Framework, and true when running under a different (specific) implementation of the CLI. When running under the Microsoft .NET Framework, the call to InternalMethod is effectively unreachable.
Add attribute [ComImport] to your class declaration
You may want to check the compiler directives as a possible option.
Unlike using a run-time "if", this will determine whether the call is included in the compiled code at all, rather than always compiling it into the code and trying to determine whether to call it at run-time (which is too late, based on your analysis).
Your use-case seems like a testing/validation scenario, which means that you don't need it compiled into the code except when the internal call will actually be made.
Note that if your use-case involves a non-.NET runtime, you should provide more information since that could drastically change the correct answer.

main() in C, C++, Java, C#

Is main() (or Main()) in C, C++, Java or C#, a user-defined function or a built-in function?
It's a user-defined function that is necessary for a program to execute. When you go to run your program in the compiled language, the main function is what is executed. For instance, in Java, if you have a function of the signature public static void main(String ... args) in a class then that class can be executed, as the JVM will execute the contents of that main method.
Example in Java:
public class Test {
public static void main(String ... args) {
System.out.println("Hello World");
}
}
...
javac Test.java
...
java Test
Results in "Hello World" being printed to the console.
I'm not sure what you mean by built-in vs. user defined. Almost no language actually gives your user-defined function the privilege of being the true entry-point into the program. C++, any .NET language, and Java all have hidden (built-in) entry point methods that in turn call your user-defined Main method (or whatever the entrypoint method for that language is called -- in .NET it can be named anything, although C# and VB.NET force it to be called Main).
So yes, virtually every language has a concept of a method that is automatically called, and this method is a user-defined method and usually mandatory. But virtually every language also has a built-in entry point method that actually sets up the framework and/or memory management for the process before invoking your user-defined "entry-point" function.
Quote from the C Standard (emphasis is mine):
5.1.2.1 Freestanding environment
In a freestanding environment (in
which C program execution may take
place without any benefit of an
operating system), the name and
type of the function called at
program startup are
implementation-defined. Any
library facilities available to a
freestanding program, other than the
minimal set required by clause 4,
are implementation-defined.
main(), in a freestanding environment, is very much a user-defined function.
It's a required user defined function (the entry point for executables)...
It is not "built-in" in any language, in a sense that there is no standard implemented-for you main() avialable.
For C/C++/Java, it is a function with a special property, namely, the function that will be called at the start of your program after all the static setup is done. E.g. entire C program's execution path is:
Do some initialization code
Call main()
Exit.
As such, it has a standard declaration (# of parameters passed from command line + array of "strings" - however the language implements that - which are the actual arguments from command line)
In C/C++, it a standard so its built in and reconized.
Java, not sure, no experience
C# - Its a part of a class so its defined by you.
All of these are defined by you -- you tell it what to do.
It's a user defined function that is called by the language's runtime library. For example, a C runtime library will grab the command line arguments and sometimes environment variables from the operating system and pass them into to your main() function.
Different language runtimes usually perform the same operation in one form or another, and will throw some sort of error if the function it tries to call doesn't exist.
It's declaration is built-in. It's definition is user supplied, or in some cases supplied by an application framework that has some other entry point, or in the case of most event-driven GUI frameworks, no single user-defined entry point.
In Java main(String[] args) is the entry point for applications by convention (to make C++ programmers comfortable). For applets or servlets the invocation of code happens differently. Note that a jar may contain any or none of these entry points and that each class may contain a main so a given jar can be invoked in many different ways as an applcation if so desired.

Categories

Resources