What is the difference between Exitcode and GetExitcodeprocess .Please provide a sample code in C# using GetExitcodeprocess
how can we convert this C++ code to C#
BOOL WINAPI GetExitCodeProcess(
_In_ HANDLE hProcess,
_Out_ LPDWORD lpExitCode
);
GetExitCodeProcess is a Win32 function that retrieves the exit code of a process that is identified by a process handle. You can pinvoke the Win32 function if you have a raw Win32 process handle:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetExitCodeProcess(IntPtr hProcess, out uint ExitCode);
The managed equivalent in the .net framework is Process.ExitCode.
Unless you have a particular reason to pinvoke the raw Win32 API it is preferable to use Process.ExitCode.
Related
I am writing code in C# that employs P/Invoke functions such as NtQuerySystemInformation. However, I notice that this function only returns information pertaining to processes of the same bitness as mine, and I want to get this information from every process on the system. Is there a way that I can invoke both the 32 bit and 64 bit versions of the function, found in ntdll.dll, from the same method?
[DllImport("ntdll.dll")]
private static extern NTStatus NtQueryObject(
IntPtr objectHandle,
ObjectInformationClass informationClass,
IntPtr informationPtr,
uint informationLength,
ref uint returnLength);
I am trying to call WaitForSingleObject method from C#, as documented here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
In order to call this function I need to create a Handle, or I need to get a Handle of type IntPtr, how can it be done?
I've tried this function that I found:
http://www.pinvoke.net/default.aspx/kernel32.WaitForSingleObject
[DllImport("coredll.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent(HANDLE lpEventAttributes, [In, MarshalAs(UnmanagedType.Bool)] bool bManualReset, [In, MarshalAs(UnmanagedType.Bool)] bool bIntialState, [In, MarshalAs(UnmanagedType.BStr)] string lpName);
Or for instance, when I am getting handle from console:
IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
It throws a DllNotFoundException.
What's the issue here?
I need it in order to run the process with this function call, and to take a dump form its process, for my ClrMd library learning.
Any help will be appreciated.
Code sample:
static void Main(string[] args)
{
var autoEvent = new AutoResetEvent(false);
//this is where I get the DllNotFoundException
WaitForSingleObject(autoEvent.Handle, WAIT_TIMEOUT );
}
[DllImport("kernel32.dll")]
static extern uint WaitForMultipleObjects(uint nCount, IntPtr[] lpHandles, bool bWaitAll, uint dwMilliseconds);
public const Int32 WAIT_TIMEOUT = 0x102;
I would not go through WinApi to get this from C#: you have EventWaitHandler and other synchronization objects in C#, use them:
WaitHandle wh = new EventWaitHandler();
//do whatever you need
...
WaitHandler.WaitOne(wh); // equivalent to WaitForSingleObject in WinApi
you can use wh.SafeWaitHandle if you really need to interop with WinApi
Also I suspect Process.GetCurrentProcess().MainWindowHandle cannot work in a Console Application, that has not any window at all
I want to call native method (WaitForMultipleObjects) which waits for some handle (don't really mind which one), then I want to see it on thread stack using ClrMd library, from dump file
OK, so what about new ManualResetEvent(false).WaitOne()? This should show up in the dump file. And it's reliable.
Just picking any existing handle is not reliable because it might be signaled or be destroyed at any time. Or, you might change its state by waiting. There is no need, a ManualResetEvent can create you a fresh handle.
My mistake I've posted WaitForMultipleObjects instead of WaitForSingleObject, the main issue was that WaitForSingleObject stayed with DllImport("coredll.dll"...) I don't know where did I found it but I did...
Sorry for the confusion
I am using c#.net to develop a winform application.My winform application is using the below components
1)Win 32 dlls (using System.Runtime.InteropServices)
2)Timers(3 in count) (System.Timers)
3)Excel Interop
The memory of the application is not at all coming down .As timers are running continuosly so i cannot dispose the
So would like to implement dispose patterns .
Is it necessary to dispose the win32 APIs apart from Excel interop.?
If necessary can you please suggest the best way to call and dispose the win32 APIs.
Some of the Win32 APIs Used in application are listed below.
DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int netConnection, int val);
[DllImport("Oleacc.dll")]
private static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint dwObjectID, byte[] riid, ref Excel.Window ptr);
[DllImport("WtsApi32.dll")]
private static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)]int dwFlags);
[DllImport("WtsApi32.dll")]
private static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd);
The hWnd parameters in your function calls are all window handles. As a general rule, whenever you have finished using a window handle in the windows API, you need to explicitly release it using the CloseHandle function
I have to call some native C functions from C# using p/invoke. So far, I had no problems marshaling the different methods and structures to C#. Where my problem resides is in the fact that many of the methods I have to call are asynchronous, and return their final results to my WinForms application through Windows Messages. For instance, I have a call to a method that has the following signature in C:
HRESULT AsyncOpenSession( LPSTR lpszLogicalName,
HANDLE hApp,
LPSTR lpszAppID,
DWORD dwTraceLevel,
DWORD dwTimeOut,
USHORT lphService,
HWND hWnd,
DWORD dwSrvcVersionsRequired,
LPWFSVERSION lpSrvcVersion,
LPWFSVERSION lpSPIVersion,
ULONG lpRequestID );
Where lpszAppID expects to receive the NAME of my application (MyApp.exe) and hWnd is a pointer to the WINDOW HANDLE of my application, which I obtain with a call to
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
public static IntPtr GetCurrentWindowHandle()
{
IntPtr handle = GetForegroundWindow();
return handle;
}
The imported signature is:
[DllImport("MSXFS.DLL", BestFitMapping = true, CharSet = CharSet.Auto, SetLastError = true)]
private static extern int AsyncOpenSession([MarshalAs(UnmanagedType.LPStr)] string lpszLogicalName,
IntPtr hApp,
[MarshalAs(UnmanagedType.LPStr)] string lpszAppID,
UInt32 dwTraceLevel,
UInt32 dwTimeOut,
out Int32 lphService,
IntPtr hWnd,
UInt32 dwSrvcVersionsRequired,
out WFSVersion lpSrvcVersion,
out WFSVersion lpSPIVersion,
out Int32 lpRequestID);
I call the method as follows:
Int32 r = AsyncOpenSession(lpszLogicalName,
appHanlder,
"MyApp.exe",
dwTraceLevel,
dwTimeOut,
out hServ,
GetCurrentWindowHandle(),
dwSrvcVersionsRequired,
out srvcVersion,
out spiVersion,
out requestID);
Initially, the method call returns a result code that indicates the requested call has been put to the execution queue. Any time after the original call the native Dll completes the execution of the request and send a Windows Message to the application by means of its windows handle and name. The Windows Message code for this method is defined as follows:
#define WM_USER 0x0400
#define OPEN_SESSION_COMPLETE (WM_USER + 1)
More info about Windows Messages here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644931(v=vs.85).aspx
In my application I have overridden the method WndProc to be able to control the Windows Messages as follows:
protected override void WndProc(ref Message m)
{
const int wm_user = 0x0400;
const int OPEN_SESSION_COMPLETE = wm_user + 1;
switch (m.Msg)
{
case OPEN_SESSION_COMPLETE:
txtEventsState.Text = m.ToString();
break;
}
base.WndProc(ref m);
}
But I never receive a Windows Message with this code. There are no error in logs or event viewer. I know my call to the method succeeded because I do not get any error code and because it is mandatory to have an opened session before calling other methods, and I can call other methods that need a session handler successfully (no error code either).
My imported signature and call to the method is in a class library project that my application is referencing. Am I doing something wrong here? Can anyone give a light on what could be happening? I do not have access to the native code, just to a test application the shows that the Windows Messages are being sent by the native C Dll.
Thank to everybody in advance.
So, here it the deal: GetForegroundWindow() is not retriving the correct Window Handle. It happens that my application has two windows. One is the main form that I use for my test and the other displays all results and logging I am doing. So, the method was actually returning the Handle of the loggin window and not the form windows.
Using this.Handle and passing that value to the native methods made everything work correctly.
Thanks to Hans for pointing this out.
I'm trying to hook a CBT hook on Windows OSes. I'm currently using Windows 7 x64.
I've read many threads talking about this issue, but none has solved my problem. The application runs well; the hook is installed and I can see some notifications coming.
Actually the problems arised is that the application is not notified about CBT hook of other processes running on the same machine.
The application is written in C# (using Microsoft .NET). Here is a running sample:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsHook
{
class Program
{
[STAThread]
static void Main(string[] args)
{
uint thid = (uint)AppDomain.GetCurrentThreadId();
bool global = true;
mHookDelegate = Marshal.GetFunctionPointerForDelegate(new HookProc(ManagedCallback));
if (global == true) {
mNativeWrapperInstance = LoadLibrary("Native_x64.dll");
thid = 0;
} else {
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
mNativeWrapperInstance = GetModuleHandle(curModule.ModuleName);
}
}
mNativeWrappedDelegate = AllocHookWrapper(mHookDelegate);
mHookHandle = SetWindowsHookEx(/*WH_CBT*/5, mNativeWrappedDelegate, mNativeWrapperInstance, thid);
if (mHookHandle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
Application.Run(new Form());
if (FreeHookWrapper(mNativeWrappedDelegate) == false)
throw new Win32Exception("FreeHookWrapper has failed");
if (FreeLibrary(mNativeWrapperInstance) == false)
throw new Win32Exception("FreeLibrary has failed");
if (UnhookWindowsHookEx(mHookHandle) == false)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
static int ManagedCallback(int code, IntPtr wParam, IntPtr lParam)
{
Trace.TraceInformation("Code: {0}", code);
if (code >= 0) {
return (0);
} else {
return (CallNextHookEx(mHookHandle, code, wParam, lParam));
}
}
delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
static IntPtr mHookHandle;
static IntPtr mHookDelegate;
static IntPtr mNativeWrapperInstance = IntPtr.Zero;
static IntPtr mNativeWrappedDelegate = IntPtr.Zero;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int hook, IntPtr callback, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
internal static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
[DllImport("Native_x64.dll")]
private static extern IntPtr AllocHookWrapper(IntPtr callback);
[DllImport("Native_x64.dll")]
private static extern bool FreeHookWrapper(IntPtr wrapper);
[DllImport("Native_x64.dll")]
private static extern int FreeHooksCount();
}
}
AllocHookWrapper and FreeHookWrapper are imported routines from a DLL (Native_x64.dll) compiler for x64 platform, located at the same directory of the application. AllocHookWrapper stores the function pointer (of the managed routine) and returns the DLL routine calling the function pointer).
Here is the code of the DLL:
#include "stdafx.h"
#include "iGecko.Native.h"
#ifdef _MANAGED
#pragma managed(push, off)
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define WRAPPER_NAME(idx) Wrapper ## idx
#define WRAPPER_IMPLEMENTATION(idx) \
LRESULT WINAPI WRAPPER_NAME(idx)(int code, WPARAM wparam, LPARAM lparam) \
{ \
if (sHooksWrapped[idx] != NULL) \
return (sHooksWrapped[idx])(code, wparam, lparam); \
else \
return (0); \
}
#define WRAPPER_COUNT 16
HOOKPROC sHooksWrapped[WRAPPER_COUNT] = { NULL };
WRAPPER_IMPLEMENTATION(0x00);
WRAPPER_IMPLEMENTATION(0x01);
WRAPPER_IMPLEMENTATION(0x02);
WRAPPER_IMPLEMENTATION(0x03);
WRAPPER_IMPLEMENTATION(0x04);
WRAPPER_IMPLEMENTATION(0x05);
WRAPPER_IMPLEMENTATION(0x06);
WRAPPER_IMPLEMENTATION(0x07);
WRAPPER_IMPLEMENTATION(0x08);
WRAPPER_IMPLEMENTATION(0x09);
WRAPPER_IMPLEMENTATION(0x0A);
WRAPPER_IMPLEMENTATION(0x0B);
WRAPPER_IMPLEMENTATION(0x0C);
WRAPPER_IMPLEMENTATION(0x0D);
WRAPPER_IMPLEMENTATION(0x0E);
WRAPPER_IMPLEMENTATION(0x0F);
const HOOKPROC sHookWrappers[] = {
WRAPPER_NAME(0x00),
WRAPPER_NAME(0x01),
WRAPPER_NAME(0x02),
WRAPPER_NAME(0x03),
WRAPPER_NAME(0x04),
WRAPPER_NAME(0x05),
WRAPPER_NAME(0x06),
WRAPPER_NAME(0x07),
WRAPPER_NAME(0x08),
WRAPPER_NAME(0x09),
WRAPPER_NAME(0x0A),
WRAPPER_NAME(0x0B),
WRAPPER_NAME(0x0C),
WRAPPER_NAME(0x0D),
WRAPPER_NAME(0x0E),
WRAPPER_NAME(0x0F)
};
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
return (TRUE);
}
#ifdef _MANAGED
#pragma managed(pop)
#endif
extern "C" IGECKONATIVE_API HOOKPROC WINAPI AllocHookWrapper(HOOKPROC wrapped)
{
for(int i = 0; i < WRAPPER_COUNT; i++) {
if (sHooksWrapped[i] == NULL) {
sHooksWrapped[i] = wrapped;
return sHookWrappers[i];
}
}
return (NULL);
}
extern "C" IGECKONATIVE_API BOOL WINAPI FreeHookWrapper(HOOKPROC wrapper)
{
for(int i = 0; i < WRAPPER_COUNT; i++) {
if (sHookWrappers[i] == wrapper) {
sHooksWrapped[i] = NULL;
return TRUE;
}
}
return (FALSE);
}
extern "C" IGECKONATIVE_API INT WINAPI FreeHooksCount()
{
int c = 0;
for(int i = 0; i < WRAPPER_COUNT; i++) {
if (sHooksWrapped[i] == NULL)
c++;
}
return (c);
}
Actually I'm interested about window related events (creation, destruction) on a certain system, but I'm actually unable to being notified by the OS...
What's going on? What have I missed?
Note that I'm running with the Administratos group.
I've found this interesting section in this page
Global hooks are not supported in the .NET Framework
You cannot implement global hooks in Microsoft .NET Framework. To install a global hook, a hook must have a native DLL export to insert itself in another process that requires a valid, consistent function to call into. This behavior requires a DLL export. The .NET Framework does not support DLL exports. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.
I thought to do the trick by implementing a native DLL containing the hook callback, which calls the managed callback. However, the managed callback is called only in the process which calls the SetWindowsHookEx routine and not called by other processes.
What are the possible workarounds?
Maybe allocating heap memory storing a process id (the managed one), and sending user messages describing the hooked functions?
What I'm trying to achieve is a system wide monitor, which detect new processes executed, detect created windows position and size, as well closed windows, moved windows, minimized/maximized windows. Successively the monitor shall detect mouse and keyboard events (always system-wide) and also it has to "emulate" mouse and keyboard events.
Every process in the same desktop has to be monitored, indepently by the archiveture (32 or 64 bit) and by the underlying framework (native or managed).
The monitor shall force process windows position, size and movements, and shall be able to act as local user in order to allow remote user to act as a local user (something like VNC).
Sorry but I don't understand the sense of "wrapping" unmanaged DLL and usage of ManagedCallback as the hook inside of managed EXE.
You should understand, that the method which you use as the callback of system wide CBT hook (parameter of SetWindowsHookEx) must be loaded in the address space of all process (it will be done a DLL injection of the module where hook function is implemented). In Windows SDK (MSDN) you can read following (see remark on http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx):
SetWindowsHookEx can be used to inject
a DLL into another process. A 32-bit
DLL cannot be injected into a 64-bit
process, and a 64-bit DLL cannot be
injected into a 32-bit process. If an
application requires the use of hooks
in other processes, it is required
that a 32-bit application call
SetWindowsHookEx to inject a 32-bit
DLL into 32-bit processes, and a
64-bit application call
SetWindowsHookEx to inject a 64-bit
DLL into 64-bit processes. The 32-bit
and 64-bit DLLs must have different
names.
Moreover you write in your question about system wide hook and use not 0 as the last parameter of SetWindowsHookEx. One more problem: as the third parameter of SetWindowsHookEx (HINSTANCE hMod) you use an instance of not the dll with the code of hook (the code of hook you have currently in the EXE).
So my suggestion: you have to write a new native code for implementation of system wide CBT hook and place it inside a DLL. I recommend you also to choose a base address (linker switch) for the DLL, which is not a standard value to reduce DLL rebasing. It is not mandatory but this will save memory resources.
Sorry for the bad news, but in my opinion your current code should be full rewritten.
UPDATED based on update in the question: One more time I repeat, that if you call in one process SetWindowsHookEx to set a CBT hook, you should give as a parameter the module instance (the start address) of a DLL and the address of a function in the DLL which implement the hook. It is not important from which process you call SetWindowsHookEx function. The DLL used as a parameter will be loaded (injected) in all processes of the same windows station which use User32.dll. So you have some native restrictions. If you want support both 32-bit and 64-bit platforms you have to implement two dlls: one 32-bit and 64-bit DLL. Moreover there are a problem with the usage of different .NET versions in the same process. It should be theoretically possible to do this only with .NET 4.0. In general it is very complex problem. And you should understand it I write about a DLL I mean not only the DLL, but all its dependencies. So if you implement a native DLL which call a managed DLL (.NET DLL) it would be not possible.
So if you want use global CBT hook you have to implement if as a two native DLLs (one 32-bit and 64-bit) and set install the hook inside of two processes (one 32-bit and 64-bit). So do exact what is described in the remark of the SetWindowsHookEx documentation http://msdn.microsoft.com/en-us/library/ms644990(VS.85).aspx (see above quote). I see no more easier ways.