C# form from DLL loaded by native C++ - c#

This a question arising from this thread: Native C++ use C# dll via proxy C++ managed dll
In a nutshell, I'm loading (my) C# extension into a native process via a DLL. The extension needs to show a form so that the user can control it. I'm using standard .NET forms, no 3rd party librarys or anything, and my form is not showing up. Worse yet, it hangs the target process. It's not using any CPU, so I get the feeling its waiting for some function to return, but never does.
Also of interest is that the "Initialize method" message box pops up, but not the "Test" message box. I've tested everything I can think of (STAthread, threads, DisableThreadLibraryCalls, plus different code locations), every way to Sunday. I'm inclined to think it's some obscure detail of Win32 interop, but I can't find anything that would seem to cause these symptoms.
Can one of you experts take a look at my code and point out what the issue is?
/// <summary>
/// Provides entry points for native code
/// </summary>
internal static class UnmanagedExports
{
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.StdCall)]
public delegate int SendRecv([MarshalAs(UnmanagedType.SafeArray)]byte[] ByteArray, UInt64 Len);
[STAThread]
[DllExport("Initialize", CallingConvention.StdCall)]
public static int Initialize(IntPtr hInstance, SendRecv Send, SendRecv Recv)
{
return DLLinterface.Initialize(hInstance, Send, Recv);
}
[DllExport("Terminate", CallingConvention.StdCall)]
public static void Terminate()
{
DLLinterface.Terminate();
}
}
internal class DLLinterface
{
static System.Threading.Thread uiThread;
[STAThread]
internal static int Initialize(IntPtr hInstance, UnmanagedExports.SendRecv Send, UnmanagedExports.SendRecv Recv)
{
MessageBox.Show("Initialize method");
try
{
uiThread = new System.Threading.Thread(Run);
uiThread.Start();
}
catch (Exception ex)
{
MessageBox.Show("Failed to load: " + ex.Message, "Infralissa error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
return 1;
}
[STAThread]
private static void Run()
{
MessageBox.Show("Test");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
internal static void Terminate()
{
MessageBox.Show("Terminating.");
if (uiThread.IsAlive)
uiThread.Abort();
}
}

It seems that the target itself was at fault. It wasn't loading the extensions directly, but instead loading a native "exensionManager.dll", where, as luck would have it, they were using DllMain to load up MY extension. In other words, I was trying to load a form under loaderlock and ran into a deadlock as. NET tried to load other assemblies.
The answer was simple, I had to show the form on a new thread. However, .NET's threading was also hanging, as it, too, required a library load which deadlocked.
In the end, I had to resort to a vanilla P/Invoke to CreateThread() directly, but the form is finally showing up.

Related

System.MissingMethodException in a dll when I shut down c# application

I found out about the error because I saw it in the windows built-in event viewer:
Description: The process was terminated due to an unhandled exception.
Exception Info: System.MissingMethodException
Stack:
at Injection.Main.DrawText_Hooked(...)
I have a c# application using easyhook. My dll critical code:
public void Run(RemoteHooking.IContext InContext, String InChannelName)
{
// Install system hook to detect calls to DrawTextExW that is made by the client and call the function DrawText_Hooked when ever this happens
try
{
DrawTextExHook = LocalHook.Create(LocalHook.GetProcAddress("user32.dll", "DrawTextExW"), new DDrawTextEx(DrawText_Hooked), this);
DrawTextExHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
}....
And my delegate to handle the hooked function is:
int DrawText_Hooked(...)
{
Interface.Read(hdc, lpString, cchText, dwDTFormat);
return DrawTextExW(hdc, lpString, cchText, ref lprc, dwDTFormat, ref dparams);
}
When I shut down my main application everything works fine unless I use Interface.Read(...): in this case, the hooked application crashes. I've read it's probably because Interface.Read(...) doesn't exist anymore once I exit my app but I don't know how to tell my dll to stop doing that or simply unload so that it doesn't try to do Interface.Read(...) and finds out it doesn't actually exist anymore. How shall I do it?
Two days looking for the answer and after posting it I discover it myself after 10':
What I did was to declare the hook static:
static LocalHook DrawTextExHook;
So from my main code, on exit, I could call a static method that points it to null, therefore stopping calling my Interface.Read(...).
public static void stopIt()
{
DrawTextExHook = null;
}

C# - cc3260mt.dll throws ArithmeticException whenever I load it

I have a WPF Application, and I must load the DLL cc3260mt.dll
I call it by using LoadLibrary(), but for whatever reason I am getting an ArithmeticException.
Here is what my code looks like :
public partial class MainWindow : Window
{
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
static extern IntPtr FreeLibrary(IntPtr hModule);
public MainWindow()
{
InitializeComponent();
try
{
string cc3260mtPath = "dll/cc3260mt.dll";
IntPtr cc3260Link = LoadLibrary(cc3260mtPath);
}
catch (Exception ex)
{
Console.WriteLine("ERROR : " + ex.Message);
}
} // <-- This is where I get the Exception.
}
When I run my code step by step, I can clearly see that the exception appears when I get out of my MainWindow() class.
Do you guys have any idea what gets me this exception ?
That is the C runtime support library for old Borland C or C++ programs. And yes, it does something that's very incompatible with .NET code in general, and WPF in particular, it reprograms the floating point unit control register. It enables hardware exceptions, triggered when a floating point operation fails. Particularly problematic in WPF because is likes to use Double.NaN a lot. Which generates an FPU exception, the CLR intercepts it and re-raises it as an ArithmeticException.
You will have to undo what this DLL did and restore the FPU control word. This is problematic, .NET doesn't give you direct access to the hardware like that. There is however a trick you can use, the CLR automatically reprograms the FPU when it handles an exception. So you can intentionally generate an exception and catch it. Like this:
IntPtr cc3260Link = LoadLibrary(cc3260mtPath);
try { throw new Exception("Ignore this please, resetting the FPU"); }
catch (Exception ex) {}
Do note the consequence of this, you'll now have the native code running without the exceptions it normally relies on. Maybe that will work.

Is it Ok to put Application.Run() method in a catch to avoid application termination?

I am trying to keep the (beta version of my) application running as much as possible,So I placed another try-catch inside Program.cs as well in cases where some critical errors occur and shut the application down unexpectedly.And in the catch i rewrote the Application.Run() method so that the application can resume itself after being terminated for what ever reason.
Is it right to have such a plan for this specific scenario?
If it is not right,Then what else is recommended in order to keep the program running?
This is the sample code demonstrating what i mean:
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Hossein;
using Pishro.Classes;
namespace Pishro
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
catch(Exception exc)
{
API.SaveAndShowLog(exc);
Application.Run(new frmMain());
}
}
}
}
Globally handling exceptions is a good idea for logging and alerting.
An automatic restart policy like yours can be useful, yes. There is a risk however: If the crash has corrupted global data-structures restarting the app can have unpredictable results like silent data corruption. For example, files might still be open and locked. Locks might not have been released. Static variables might be in an undefined state. Rogue threads might still be running, unaware that the application UI was destroyed.
I recommend that you restart the app by starting a new process of your application. Let the old process die.
I think your question involves a deeper question.. Should I catch all the exceptions?
To keep going you could catch them all.. but all those possible exceptions that you don't expect or not know are probably bugs.
Maybe you should try to implement better error handling approach within your app. So all the exceptions are known or expected.
Instead of wrapping a try catch around your application run method, consider handling the exceptions with events.
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
MessageBox.Show("Exception handled");
}
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
}
Mainly the thread exception is the one you want but ideally - you would want to set up some form of logging/flagging the error to the user and still dispose of the program because it may cause the program to continue in an unfit state. Please put a button on your form and in the click event throw new Exception(""); and then the message box should display.

How to implement Global Hotkeys in C#?

I need to write an application which globally intercepts Alt+Shift+S.
What I did is I created a DLL which sets global hooks:
namespace Hotkeydll
{
public class MyHotKey
{
public static void setHooks()
{
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
}
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
//write something into file
}
}
}
Then I created a program which loads this DLL and set the hook:
using Hotkeydll;
namespace IWFHotkeyStarter
{
class Program
{
static void Main(string[] args)
{
MyHotKey.setHooks();
}
}
}
Now the problem is that the hotkey doesn't work.
It looks like the DLL is not loaded permanently into memory. I see that I can delete the dll file from file system.
So please advise what I am doing wrong?
Should I use a different approach?
Thank you.
Your Main() method sets the hooks, then immediately exits and terminates the program. Furthermore, you need a message loop to make the hook callback work. That requires a Windows Forms or WPF app. Using a real hot key instead of a hook now also becomes an option. Check this thread for an example, C# is further down the page.
Keyboard hooks are usually not the right way to get global hotkeys.
Use RegisterHotkey whenever possible.

Check if a DLL is present in the system

quick question. I want to find out if a DLL is present in the system where my application is executing.
Is this possible in C#? (in a way that would work on ALL Windows OS?)
For DLL i mean a non-.NET classic dll (a Win32 dll)
(Basically I want to make a check cause I'm using a DLL that may or may not be present on the user system, but I don't want the app to crash without warning when this is not present :P)
Call the LoadLibrary API function:
[DllImport("kernel32", SetLastError=true)]
static extern IntPtr LoadLibrary(string lpFileName);
static bool CheckLibrary(string fileName) {
return LoadLibrary(fileName) == IntPtr.Zero;
}
When using platform invoke calls in .NET, you could use the Marshal.PrelinkAll(Type) method:
Setup tasks provide early initialization and are performed
automatically when the target method is invoked. First-time tasks
include the following:
Verifying that the platform invoke metadata is correctly formatted.
Verifying that all the managed types are valid parameters of platform
invoke functions.
Locating and loading the unmanaged DLL into the process.
Locating the entry point in the process.
As you can see, it performs additional checks other than if the dll exists, like locating the entry points (e.g if SomeMethod() and SomeMethod2() actually exist in the process like in the following code).
using System.Runtime.InteropServices;
public class MY_PINVOKES
{
[DllImport("some.dll")]
private static void SomeMethod();
[DllImport("some.dll")]
private static void SomeMethod2();
}
Then use a try/catch strategy to perform your check:
try
{
// MY_PINVOKES class where P/Invokes are
Marshal.PrelinkAll( typeof( MY_PINVOKES) );
}
catch
{
// Handle error, DLL or Method may not exist
}
Actually it does not throw FileNotFoundException.
Also for that one needs to check in multiple places for path, for the LoadLibrary
There is a standard exception in .net the is derived from TypeLoadException, that is DllNotFoundException.
Best way is to wrap a method/PInvoke call in try..catch and handle the DllNotFoundException since .net will check for application path as well as any other paths set as part of PATH OS Environment variable.
[DllImport("some.dll")]
private static void SomeMethod();
public static void SomeMethodWrapper() {
try {
SomeMethod();
} catch (DllNotFoundException) {
// Handle your logic here
}
}
Call LoadLibrary.
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx
I'm assuming this is a PInvoke call?
If so the easiest way to make this determine if it's present is to make the call and catch the exception that results if the file does not exist.
[DllImport("some.dll")]
private static void SomeMethod();
public static void SomeMethodWrapper() {
try {
SomeMethod();
} catch (DllNotFoundException) {
// Do Nothing
}
}

Categories

Resources