I am trying to minimize the window with the title located in the string p (specified by the user at runtime). The window is guaranteed to be a main window, because the user can only choose from main windows. I have tried showCmd, flags, and a mixture of the two, but every time, regardless of whether the window is minimized, I am shown the dialog box that states "Minimizing". How can I fix it?
private void button1_Click(object sender, EventArgs e)
{
foreach (Process proc in Process.GetProcesses())
{
if (proc.MainWindowTitle.Contains(p))
{
IntPtr handle = proc.Handle;
Program.WINDOWPLACEMENT wp = new Program.WINDOWPLACEMENT();
Program.GetWindowPlacement(handle, ref wp);
if ((wp.showCmd & 2) == 2)
{
wp.showCmd = 9;
MessageBox.Show("Restoring");
}
else
{
wp.showCmd = 2;
MessageBox.Show("Minimizing");
}
wp.length = Marshal.SizeOf(wp);
Program.SetWindowPlacement(handle, ref wp);
break;
}
}
}
What I'm using as p -
string p;
PictureBox i;
bool windowShowing = false;
bool minimized = false;
public TaskbarItem(string window)
{
InitializeComponent();
p = window;
button1.Text = window;
}
To get the window:
class WindowEnumerator
{
public delegate bool EnumDelegate(IntPtr hWnd, int lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);
[DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
public static List<IntPtr> GetChildWindows(IntPtr parent)
{
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
public static LinkedList<IntPtr> EnumMethod2(bool includeChild)
{
LinkedList<IntPtr> pss = new LinkedList<IntPtr>();
Process[] ps = Process.GetProcesses();
foreach (Process p in ps)
{
string s = p.MainWindowTitle;
if (s.Equals("") || s.Equals("Mod_Taskbar"))
{
continue;
}
LinkedListNode<IntPtr> node = new LinkedListNode<IntPtr>(p.MainWindowHandle);
pss.AddLast(node);
if (includeChild){
List<IntPtr> l = GetChildWindows(p.MainWindowHandle);
foreach (IntPtr i in l)
{
StringBuilder stb = new StringBuilder(255);
WindowEnumerator.GetWindowText(i, stb, 255);
if (stb.ToString().StartsWith("Address:") || stb.ToString().EndsWith("View") || stb.ToString().EndsWith("Control") ||
stb.ToString().EndsWith("Bar") || stb.ToString().EndsWith("bar") || stb.ToString().Contains("Host"))
{
continue;
}
if (Vars.excludes.Contains(stb.ToString()))
{
continue;
}
pss.AddAfter(node, i);
}
}
}
return pss;
}
private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
list.Add(handle);
return true;
}
}
And:
private void LoadWindows(object sender, EventArgs e)
{
panel1.Controls.Clear();
foreach (IntPtr p in WindowEnumerator.EnumMethod2(false))
{
StringBuilder stb = new StringBuilder(255);
WindowEnumerator.GetWindowText(p, stb, 255);
TaskbarItem t = new TaskbarItem(stb.ToString());
t.Dock = DockStyle.Left;
panel1.Controls.Add(t);
}
}
Did you check what value the wp.showCmd has?
Try with this code:
foreach (Process proc in Process.GetProcesses())
{
if (proc.MainWindowTitle.Contains(p))
{
IntPtr handle = proc.Handle;
Program.WINDOWPLACEMENT wp = new Program.WINDOWPLACEMENT();
Program.GetWindowPlacement(handle, ref wp);
if ((wp.showCmd & 2) == 2)
{
wp.showCmd = 9;
MessageBox.Show("Restoring");
}
else
{
wp.showCmd = 2;
MessageBox.Show("Minimizing");
}
wp.length = Marshal.SizeOf(wp);
Program.SetWindowPlacement(handle, ref wp);
break;
}
}
this.WindowState = FormWindowState.Minimized;
Related
I'm using the full class provided as best answer in: C# Hook Global Keyboard Events - .net 4.0 without any changes to it. However, when pressing a key when focussed on the powerpoint, I get the following error:
Exception thrown: 'System.Runtime.InteropServices.COMException'
I open the powerpoint by:
PowerPoint.Presentation presentation = (PowerPoint.Presentation)PowerPointItems[0];
PowerPoint.Application application = presentation.Application;
PowerPoint.SlideShowSettings settings = presentation.SlideShowSettings;
settings.ShowType = (PowerPoint.PpSlideShowType)1;
settings.ShowPresenterView = MsoTriState.msoFalse;
PowerPoint.SlideShowWindow sw = settings.Run();
sw.View.AcceleratorsEnabled = MsoTriState.msoFalse;
presentation.SlideShowWindow.View.GotoSlide(1);
presentation.SlideShowWindow.View.FirstAnimationIsAutomatic();
The callback function looks like:
private static void Kh_KeyDown(Keys key, bool Shift, bool Ctrl, bool Alt)
{
Console.WriteLine("a");
PowerPoint.Presentation presentation = (PowerPoint.Presentation)PowerPointItems[0];
Console.WriteLine("b");
int nr_slides = presentation.Slides.Count;
Console.WriteLine("c");
}
However, while a and b are printed in the output, c is not but the exception is. This makes me think for some reason the exception is thrown because of the line
int nr_slides = presentation.Slides.Count;
Any thought on why this could be the case?
The code provided on C# Hook Global Keyboard Events - .net 4.0:
public class KeyboardHook : IDisposable
{
bool Global = false;
public delegate void ErrorEventHandler(Exception e);
public delegate void LocalKeyEventHandler(Keys key, bool Shift, bool Ctrl, bool Alt);
public event LocalKeyEventHandler KeyDown;
public event LocalKeyEventHandler KeyUp;
public event ErrorEventHandler OnError;
public delegate int CallbackDelegate(int Code, IntPtr W, IntPtr L);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct KBDLLHookStruct
{
public Int32 vkCode;
public Int32 scanCode;
public Int32 flags;
public Int32 time;
public Int32 dwExtraInfo;
}
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SetWindowsHookEx(HookType idHook, CallbackDelegate lpfn, IntPtr hInstance, int threadId);
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(IntPtr idHook);
[DllImport("user32", CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(IntPtr idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int GetCurrentThreadId();
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
public enum HookType : int
{
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}
private IntPtr HookID = IntPtr.Zero;
CallbackDelegate TheHookCB = null;
//Start hook
public KeyboardHook(bool Global)
{
this.Global = Global;
TheHookCB = new CallbackDelegate(KeybHookProc);
if (Global)
{
IntPtr hInstance = LoadLibrary("User32");
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, TheHookCB,
hInstance, //0 for local hook. or hwnd to user32 for global
0); //0 for global hook. eller thread for hooken
}
else
{
HookID = SetWindowsHookEx(HookType.WH_KEYBOARD, TheHookCB,
IntPtr.Zero, //0 for local hook. or hwnd to user32 for global
GetCurrentThreadId()); //0 for global hook. or thread for the hook
}
}
public void test()
{
if (OnError != null) OnError(new Exception("test"));
}
bool IsFinalized = false;
~KeyboardHook()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
public void Dispose()
{
if (!IsFinalized)
{
UnhookWindowsHookEx(HookID);
IsFinalized = true;
}
}
[STAThread]
//The listener that will trigger events
private int KeybHookProc(int Code, IntPtr W, IntPtr L)
{
KBDLLHookStruct LS = new KBDLLHookStruct();
if (Code < 0)
{
return CallNextHookEx(HookID, Code, W, L);
}
try
{
if (!Global)
{
if (Code == 3)
{
IntPtr ptr = IntPtr.Zero;
int keydownup = L.ToInt32() >> 30;
if (keydownup == 0)
{
if (KeyDown != null) KeyDown((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
if (keydownup == -1)
{
if (KeyUp != null) KeyUp((Keys)W, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
//System.Diagnostics.Debug.WriteLine("Down: " + (Keys)W);
}
}
else
{
KeyEvents kEvent = (KeyEvents)W;
Int32 vkCode = Marshal.ReadInt32((IntPtr)L); //Leser vkCode som er de første 32 bits hvor L peker.
if (kEvent != KeyEvents.KeyDown && kEvent != KeyEvents.KeyUp && kEvent != KeyEvents.SKeyDown && kEvent != KeyEvents.SKeyUp)
{
}
if (kEvent == KeyEvents.KeyDown || kEvent == KeyEvents.SKeyDown)
{
if (KeyDown != null) KeyDown((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
if (kEvent == KeyEvents.KeyUp || kEvent == KeyEvents.SKeyUp)
{
if (KeyUp != null) KeyUp((Keys)vkCode, GetShiftPressed(), GetCtrlPressed(), GetAltPressed());
}
}
}
catch (Exception e)
{
if (OnError != null) OnError(e);
//Ignore all errors...
}
return CallNextHookEx(HookID, Code, W, L);
}
public enum KeyEvents
{
KeyDown = 0x0100,
KeyUp = 0x0101,
SKeyDown = 0x0104,
SKeyUp = 0x0105
}
[DllImport("user32.dll")]
static public extern short GetKeyState(System.Windows.Forms.Keys nVirtKey);
public static bool GetCapslock()
{
return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.CapsLock)) & true;
}
public static bool GetNumlock()
{
return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.NumLock)) & true;
}
public static bool GetScrollLock()
{
return Convert.ToBoolean(GetKeyState(System.Windows.Forms.Keys.Scroll)) & true;
}
public static bool GetShiftPressed()
{
int state = GetKeyState(System.Windows.Forms.Keys.ShiftKey);
if (state > 1 || state < -1) return true;
return false;
}
public static bool GetCtrlPressed()
{
int state = GetKeyState(System.Windows.Forms.Keys.ControlKey);
if (state > 1 || state < -1) return true;
return false;
}
public static bool GetAltPressed()
{
int state = GetKeyState(System.Windows.Forms.Keys.Menu);
if (state > 1 || state < -1) return true;
return false;
}
}
In general, you need to catch the COMException, interrogate ErrorCode (HRESULT) property, and search for the error code definition; this will provide direction on how to troubleshoot the issue further.
Reference: COMException Class: Handling a COMException exception on MSDN
One idea, without knowing the error code, is this interaction might need to occur on the thread which instantiated the control. You might be able to resolve this by using Invoke or BeginInvoke.
Control.BeginInvoke Method
If you add more details to the question I will try to provide a better answer.
An object reference is required for the non-static field, method, or property 'injector.SI(uint, string)' I dont really understand what is the error or the mistake (Visual Studio C# windows form app it would be a really big help if anyone can fix this because I cant find the solution at all Ive been searching for quite a bit of time but still cant find any solution
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Hoshiyomi.functions
{
public partial class injector : Form
{
public injector()
{
InitializeComponent();
Process[] PC = Process.GetProcesses().Where(p => (long)p.MainWindowHandle !=0).ToArray();
comboBox1.Items.Clear();
foreach (Process p in PC)
{
comboBox1.Items.Add(p.ProcessName);
}
}
private void injector_Load(object sender, System.EventArgs e)
{
this.FormBorderStyle = FormBorderStyle.FixedSingle;
}
private static string DLLP { get; set; }
private void flatButton1_Click(object sender, EventArgs e)
{
try
{
OpenFileDialog OFD = new OpenFileDialog();
OFD.InitialDirectory = #"C:\";
OFD.Title = "NotWeeb | Locate DLL";
OFD.DefaultExt = "dll";
OFD.Filter = "DLL Files (*.dll)|*.dll";
OFD.CheckFileExists = true;
OFD.CheckPathExists = true;
OFD.ShowDialog();
textBox1.Text = OFD.FileName;
DLLP = OFD.FileName;
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
DLLP = textBox1.Text;
}
private void flatButton3_Click(object sender, EventArgs e)
{
Process[] PC = Process.GetProcesses().Where(p => (long)p.MainWindowHandle != 0).ToArray();
comboBox1.Items.Clear();
foreach (Process p in PC)
{
comboBox1.Items.Add(p.ProcessName);
}
}
static readonly IntPtr INTPTR_ZERO = (IntPtr)0;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenProcess(uint dwDesiredAccess, int bInheritHandle, GraphicsUnit dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr Module, string lpProcName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpBaseAddress, byte[] Buffer, uint size, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, uint size, int lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttribute, IntPtr dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
public static int Inject(string PN, string DLLP)
{
if (!File.Exists(DLLP)) { return 1; } //1 not exist
uint _procId = 0;
Process[] _procs = Process.GetProcesses();
for (int i = 0; i < _procs.Length; i++)
{
if (_procs[i].ProcessName == PN)
{
_procId = (uint)_procs[i].Id;
}
}
if (_procId == 0) { return 2; } //2 not exist
if (!SI(_procId, DLLP))
{
return 3; //3 inject fail
}
return 4; //4 inject success
}
public bool SI(uint P, string DLLP)
{
IntPtr hndProc = OpenProcess((0x2 | 0x8 | 0x10 | 0x20 | 0x400), 1, P);
if (hndProc == INTPTR_ZERO) { return false; }
IntPtr lpAddress = VirtualAllocEx(hndProc, (IntPtr)null, (IntPtr)DLLP.Length, (0x1000 | 0x2000), 0x40);
if (lpAddress == INTPTR_ZERO)
{
return false;
}
byte[] bytes = Encoding.ASCII.GetBytes(DLLP);
if (WriteProcessMemory(hndProc, lpAddress, bytes, (uint)bytes.Length, 0) == 0)
{
return false;
}
CloseHandle(hndProc);
return true;
}
private IntPtr OpenProcess(int v1, int v2, uint p)
{
throw new NotImplementedException();
}
private IntPtr VirtualAllocEx(IntPtr hndProc, IntPtr intPtr, IntPtr length, int v1, int v2)
{
throw new NotImplementedException();
}
private void flatButton2_Click(object sender, EventArgs e)
{
int Result = Inject(comboBox1.Text, DLLP);
if (Result == 1)
{
MessageBox.Show("File doesn't exist");
}
else if (Result == 2)
{
MessageBox.Show("Process doesn't exist");
}
else if (Result == 3)
{
MessageBox.Show("Injection fail");
}
else if (Result == 4)
{
MessageBox.Show("Injection Succeeded");
}
}
}
}
enter image description here
I want to find which files is currently opened by Excel, Word of PDF process.
In x64dbg i can see info about process and can see needed file, but C# and WMI looks like do not allow to get such information.
The handle.exe is not very good solution, I do not want to use it and parse data.
So is there any way to do it using C# and WMI, if not, then what Win32 API I can use to find Handles associated with process.
The ntdll.dll ->NtQueryInformationProcess it is allows me to get address of process but how to use it to read Handles?
Thanks to all, I have found a solution.NtQueryObject hang when FileTypePipe
So there is a lot of solutions in the internet but most of them have problem with hanging when getting name for FileTypePipe :)
public class ProcessUtility
{
/// <summary>
/// https://www.geoffchappell.com/studies/windows/km/ntoskrnl/api/ex/sysinfo/handle_table_entry.htm?ts=0,242
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct SYSTEM_HANDLE_INFORMATION
{ // Information Class 16
public ushort ProcessID;
public ushort CreatorBackTrackIndex;
public byte ObjectType;
public byte HandleAttribute;
public ushort Handle;
public IntPtr Object_Pointer;
public IntPtr AccessMask;
}
private enum OBJECT_INFORMATION_CLASS : int
{
ObjectBasicInformation = 0,
ObjectNameInformation = 1,
ObjectTypeInformation = 2,
ObjectAllTypesInformation = 3,
ObjectHandleInformation = 4
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
private struct OBJECT_NAME_INFORMATION
{ // Information Class 1
public UNICODE_STRING Name;
}
[StructLayout(LayoutKind.Sequential)]
private struct UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
public IntPtr Buffer;
}
[Flags]
private enum PROCESS_ACCESS_FLAGS : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
private enum FileType : uint
{
FileTypeChar = 0x0002,
FileTypeDisk = 0x0001,
FileTypePipe = 0x0003,
FileTypeRemote = 0x8000,
FileTypeUnknown = 0x0000,
}
[DllImport("ntdll.dll")]
private static extern uint NtQuerySystemInformation(int SystemInformationClass, IntPtr SystemInformation, int SystemInformationLength, ref int returnLength);
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(PROCESS_ACCESS_FLAGS dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, out IntPtr lpTargetHandle, uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);
[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
[DllImport("ntdll.dll")]
private static extern int NtQueryObject(IntPtr ObjectHandle, int ObjectInformationClass, IntPtr ObjectInformation, int ObjectInformationLength, ref int returnLength);
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);
[DllImport("kernel32.dll")]
private static extern bool GetHandleInformation(IntPtr hObject, out uint lpdwFlags);
[DllImport("kernel32.dll")]
private static extern FileType GetFileType(IntPtr hFile);
private const int MAX_PATH = 260;
private const uint STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;
private const int DUPLICATE_SAME_ACCESS = 0x2;
private const uint FILE_SEQUENTIAL_ONLY = 0x00000004;
private const int CNST_SYSTEM_HANDLE_INFORMATION = 0x10;
private const int OBJECT_TYPE_FILE = 0x24;
public static List<string> FindFilesByExtension(List<Process> target_processes, List<string> target_extensions)
{
List<string> aFilePaths = new List<string>();
if (target_extensions == null || target_extensions.Count == 0)
{
throw new Exception("Exceptions not defined");
}
foreach (Process process in target_processes)
{
List<string> aProcessFiles = GetPrcessFiles(target_processes);
foreach (string file_path in aProcessFiles)
{
if (target_extensions.Contains(Path.GetExtension(file_path.ToLower()))
&& !Path.GetFileName(file_path).StartsWith("~"))
{
aFilePaths.Add(file_path);
}
}
}
return aFilePaths;
}
public static List<string> GetPrcessFiles(List<Process> target_processes)
{
List<string> aFiles = new List<string>();
foreach (Process process in target_processes)
{
List<SYSTEM_HANDLE_INFORMATION> aHandles = GetFileHandles(process).ToList();
foreach (SYSTEM_HANDLE_INFORMATION handle_info in aHandles)
{
string file_path = GetFilePath(handle_info, process);
if (!string.IsNullOrEmpty(file_path))
{
aFiles.Add(file_path);
}
}
}
return aFiles;
}
private static IEnumerable<SYSTEM_HANDLE_INFORMATION> GetFileHandles(Process process)
{
List<SYSTEM_HANDLE_INFORMATION> aHandles = new List<SYSTEM_HANDLE_INFORMATION>();
int handle_info_size = Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION()) * 20000;
IntPtr ptrHandleData = IntPtr.Zero;
try
{
ptrHandleData = Marshal.AllocHGlobal(handle_info_size);
int nLength = 0;
while (NtQuerySystemInformation(CNST_SYSTEM_HANDLE_INFORMATION, ptrHandleData, handle_info_size, ref nLength) == STATUS_INFO_LENGTH_MISMATCH)
{
handle_info_size = nLength;
Marshal.FreeHGlobal(ptrHandleData);
ptrHandleData = Marshal.AllocHGlobal(nLength);
}
long handle_count = Marshal.ReadIntPtr(ptrHandleData).ToInt64();
IntPtr ptrHandleItem = ptrHandleData + Marshal.SizeOf(ptrHandleData);
for (long lIndex = 0; lIndex < handle_count; lIndex++)
{
SYSTEM_HANDLE_INFORMATION oSystemHandleInfo = Marshal.PtrToStructure<SYSTEM_HANDLE_INFORMATION>(ptrHandleItem);
ptrHandleItem += Marshal.SizeOf(new SYSTEM_HANDLE_INFORMATION());
if (oSystemHandleInfo.ProcessID != process.Id || oSystemHandleInfo.ObjectType != OBJECT_TYPE_FILE)
{ continue; }
aHandles.Add(oSystemHandleInfo);
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
Marshal.FreeHGlobal(ptrHandleData);
}
return aHandles;
}
private static string GetFilePath(SYSTEM_HANDLE_INFORMATION systemHandleInformation, Process process)
{
IntPtr ipHandle = IntPtr.Zero;
IntPtr openProcessHandle = IntPtr.Zero;
IntPtr hObjectName = IntPtr.Zero;
try
{
PROCESS_ACCESS_FLAGS flags = PROCESS_ACCESS_FLAGS.DupHandle | PROCESS_ACCESS_FLAGS.VMRead;
openProcessHandle = OpenProcess(flags, false, process.Id);
if (!DuplicateHandle(openProcessHandle, new IntPtr(systemHandleInformation.Handle), GetCurrentProcess(), out ipHandle, 0, false, DUPLICATE_SAME_ACCESS))
{
return null;
}
if (GetFileType(ipHandle) != FileType.FileTypeDisk)
{ return null; }
int nLength = 0;
hObjectName = Marshal.AllocHGlobal(256 * 1024);
while ((uint)(NtQueryObject(ipHandle, (int)OBJECT_INFORMATION_CLASS.ObjectNameInformation, hObjectName, nLength, ref nLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
Marshal.FreeHGlobal(hObjectName);
if (nLength == 0)
{
Console.WriteLine("Length returned at zero!");
return null;
}
hObjectName = Marshal.AllocHGlobal(nLength);
}
OBJECT_NAME_INFORMATION objObjectName = Marshal.PtrToStructure<OBJECT_NAME_INFORMATION>(hObjectName);
if (objObjectName.Name.Buffer != IntPtr.Zero)
{
string strObjectName = Marshal.PtrToStringUni(objObjectName.Name.Buffer);
return GetRegularFileNameFromDevice(strObjectName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Marshal.FreeHGlobal(hObjectName);
CloseHandle(ipHandle);
CloseHandle(openProcessHandle);
}
return null;
}
private static string GetRegularFileNameFromDevice(string strRawName)
{
string strFileName = strRawName;
foreach (string strDrivePath in Environment.GetLogicalDrives())
{
var sbTargetPath = new StringBuilder(MAX_PATH);
if (QueryDosDevice(strDrivePath.Substring(0, 2), sbTargetPath, MAX_PATH) == 0)
{
return strRawName;
}
string strTargetPath = sbTargetPath.ToString();
if (strFileName.StartsWith(strTargetPath))
{
strFileName = strFileName.Replace(strTargetPath, strDrivePath.Substring(0, 2));
break;
}
}
return strFileName;
}
}
i have my program that Captures weighing and send it to a open window.
its work excellent , except with a single software - Microsoft Word
I have tried everything and have no idea why.
my code:
this is the GlobalKeyBoardHook.cs class
public class GlobalKeyboardHook
{
[DllImport("user32.dll")]
static extern int CallNextHookEx(IntPtr hhk, int code, int wParam, ref keyBoardHookStruct lParam);
[DllImport("user32.dll")]
static extern IntPtr SetWindowsHookEx(int idHook, LLKeyboardHook callback, IntPtr hInstance, uint theardID);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);
public delegate int LLKeyboardHook(int Code, int wParam, ref keyBoardHookStruct lParam);
public struct keyBoardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 0x0100;
const int WM_KEYUP = 0x0101;
const int WM_SYSKEYDOWN = 0x0104;
const int WM_SYSKEYUP = 0x0105;
LLKeyboardHook llkh;
public List<Keys> HookedKeys = new List<Keys>();
IntPtr Hook = IntPtr.Zero;
public event KeyEventHandler KeyDown;
public event KeyEventHandler KeyUp;
// This is the Constructor. This is the code that runs every time you create a new GlobalKeyboardHook object
public GlobalKeyboardHook()
{
llkh = new LLKeyboardHook(HookProc);
// This starts the hook. You can leave this as comment and you have to start it manually (the thing I do in the tutorial, with the button)
// Or delete the comment mark and your hook will start automatically when your program starts (because a new GlobalKeyboardHook object is created)
// That's why there are duplicates, because you start it twice! I'm sorry, I haven't noticed this...
// hook(); <-- Choose!
}
~GlobalKeyboardHook()
{ unhook(); }
public void hook()
{
IntPtr hInstance = LoadLibrary("User32");
Hook = SetWindowsHookEx(WH_KEYBOARD_LL, llkh, hInstance, 0);
}
public void unhook()
{
UnhookWindowsHookEx(Hook);
}
public int HookProc(int Code, int wParam, ref keyBoardHookStruct lParam)
{
if (Code >= 0)
{
Keys key = (Keys)lParam.vkCode;
if (HookedKeys.Contains(key))
{
KeyEventArgs kArg = new KeyEventArgs(key);
if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
KeyDown(this, kArg);
else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
KeyUp(this, kArg);
if (kArg.Handled)
return 1;
}
}
return CallNextHookEx(Hook, Code, wParam, ref lParam);
}
// --- from here start the program --
GlobalKeyboardHook gHook;
gHook = new GlobalKeyboardHook(); // Create a new GlobalKeyboardHook
gHook.KeyDown += new KeyEventHandler(gHook_KeyDown);
foreach (Keys key in Enum.GetValues(typeof(Keys)))
{
gHook.HookedKeys.Add(key);
}
gHook.hook();
public void gHook_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyValue == KeyPressg) //Pause-Break //19
{
ProccName = (GetActiveWindowTitle().ToString());
Start(ProccName);
gHook.unhook();
gHook.hook();
}
else
{
}
}
private string GetActiveWindowTitle()
{
const int nChars = 256;
StringBuilder Buff = new StringBuilder(nChars);
IntPtr handle = GetForegroundWindow();
if (GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return null;
}
[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public void Start(string NAME)
{
MSG = lblMSG.Text.Trim();
IntPtr zero = IntPtr.Zero;
for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++)
{
Thread.Sleep(500);
zero = FindWindow(null, NAME);
}
if (zero != IntPtr.Zero)
{
try
{
string text = lblMSG.Text.Trim();
text = text.Replace("gHook", "");
//OLD
//foreach (char c in text)
// SendKeys.SendWait(c.ToString());
//NEW
if (text.Length == 0) return;
SendKeys.SendWait(text);
if (MyParam._KeyAfter == "Enter")
{
MyParam.FromKEY = true;
SendKeys.SendWait("{ENTER}");
}
else if (MyParam._KeyAfter == "TAB")
{
SendKeys.SendWait("{TAB}");
}
else if (MyParam._KeyAfter == "Key Down")
{
SendKeys.SendWait("{DOWN}");
}
SendKeys.Flush();
}
catch { }
}
}
Any ideas why ?
thanks
EDIT
i fount the problem place:
public void Start(string NAME)
{
// --> NAME Contain --> Word - 123.docx for example when Word window open
MSG = lblMSG.Text.Trim();
IntPtr zero = IntPtr.Zero;
for (int i = 0; (i < 60) && (zero == IntPtr.Zero); i++)
{
Thread.Sleep(500);
zero = FindWindow(null, NAME); // <-- in Word zero Always Contain 0 And never goes on in the code so stuck
}
// <--- the program stops here and stuck
if (zero != IntPtr.Zero)
{
To clear things up before you mention the most obvious choice, I am already calling ShowDialog and not the Show method!!!
I would like to block the close (invoked from a different thread) off an WPF window if a OpenFileDialog is open.
Here is the code I have (reduced to show my problem):
public class FooWindow : Window
{
public FooWindow()
{
InitializeComponent();
this.Closing += OnClosing;
}
public void OpenDialogAndCloseMe()
{
var ofd = new OpenFileDialog();
Thread th = new Thread(() => CloseMe());
th.Start();
ofd.ShowDialog(this);
}
public void CloseMe()
{
System.Threading.Thread.Sleep(2000); //give the OpenFileDialog time to pop up...
//since this method gets called from a different thread invoke it...
this.Dispatcher.Invoke(() => this.Close());
}
private void OnClosing(object sender, CancelEventArgs e)
{
//check if OpenFileDialog is still open and block the close...
e.Cancel = true;
}
}
The problem I am facing is the OnClosing part, how would I get the OpenFileDialog (or any other Dialog in that case).
I have searched the web and found Win32 methods like:
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumedWindow callback, ArrayList lParam);
[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
I have tried them both but they return 0 children, any ideas what's going wrong?
Here is the full code I tried so far:
//replace the above OnClosing with this implementation... all 3 return false
private void OnClosing(object sender, CancelEventArgs e)
{
//check if OpenFileDialog is still open and block the close...
var hWnd = new WindowInteropHelper(this).Handle;
if (WindowHandling.GetChildren(hWnd).Any())
e.Cancel = true;
if (WindowHandling.GetChildrenV2(hWnd).Any())
e.Cancel = true;
if (WindowHandling.GetChildrenV3(hWnd).Any())
e.Cancel = true;
}
public static class WindowHandling
{
private delegate bool EnumedWindow(IntPtr handleWindow, ArrayList handles);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumedWindow callback, ArrayList lParam);
[DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
private static bool GetWindowHandle(IntPtr windowHandle, ArrayList windowHandles)
{
windowHandles.Add(windowHandle);
return true;
}
public static IEnumerable<IntPtr> GetChildren(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
return Enumerable.Empty<IntPtr>();
var x = new WindowHandleInfo(hWnd);
return x.GetAllChildHandles();
}
public static IEnumerable<IntPtr> GetChildrenV2(IntPtr hWnd)
{
var windowHandles = new ArrayList();
EnumedWindow callBackPtr = GetWindowHandle;
EnumChildWindows(hWnd, callBackPtr, windowHandles);
return windowHandles.OfType<IntPtr>();
}
public static IEnumerable<IntPtr> GetChildrenV3(IntPtr hParent)
{
var result = new List<IntPtr>();
var ct = 0;
var maxCount = 100;
var prevChild = IntPtr.Zero;
while (true && ct < maxCount)
{
var currChild = FindWindowEx(hParent, prevChild, null, null);
if (currChild == IntPtr.Zero)
break;
result.Add(currChild);
prevChild = currChild;
++ct;
}
return result;
}
//http://stackoverflow.com/questions/1363167/how-can-i-get-the-child-windows-of-a-window-given-its-hwnd
private class WindowHandleInfo
{
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);
private readonly IntPtr _mainHandle;
public WindowHandleInfo(IntPtr handle)
{
_mainHandle = handle;
}
public IEnumerable<IntPtr> GetAllChildHandles()
{
var childHandles = new List<IntPtr>();
var gcChildhandlesList = GCHandle.Alloc(childHandles);
var pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);
try
{
var childProc = new EnumWindowProc(EnumWindow);
var x = EnumChildWindows(this._mainHandle, childProc, pointerChildHandlesList);
if (x == false)
{
var error = Marshal.GetLastWin32Error();
}
}
finally
{
gcChildhandlesList.Free();
}
return childHandles;
}
private static bool EnumWindow(IntPtr hWnd, IntPtr lParam)
{
var gcChildhandlesList = GCHandle.FromIntPtr(lParam);
if (gcChildhandlesList.Target == null)
return false;
var childHandles = gcChildhandlesList.Target as List<IntPtr>;
if (childHandles != null)
childHandles.Add(hWnd);
return true;
}
}
}
You can solve this with a boolean value tracking if it's open or not:
bool dialogOpen = false;
public void OpenDialogAndCloseMe()
{
var ofd = new OpenFileDialog();
Thread th = new Thread(() => CloseMe());
th.Start();
dialogOpen = true;
ofd.ShowDialog(this);
dialogOpen = false;
}
private void OnClosing(object sender, CancelEventArgs e)
{
//check if OpenFileDialog is still open and block the close...
if(dialogOpen)
{
e.Cancel = true;
}
}