C# console application lose focus - c#

I have about 15 different console apps on my local PC and they are running with different time periods as scheduled tasks.
Since I am using this computer as personal usage (such as surfing on YouTube or Watching Movies)
They are jumping on my screen but I have to always minimize them manually.
My goal is, I want them to first appear (which is already doing) and lose automatically focus after a couple of seconds.
Is it possible with console apps on Windows?

If you want to minimize console window, you can use WinApi
const Int32 SW_MINIMIZE = 6;
[DllImport("Kernel32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr GetConsoleWindow();
[DllImport("User32.dll", CallingConvention = CallingConvention.StdCall, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowWindow([In] IntPtr hWnd, [In] Int32 nCmdShow);
private static void MinimizeConsoleWindow()
{
IntPtr hWndConsole = GetConsoleWindow();
ShowWindow(hWndConsole, SW_MINIMIZE);
}
Usage:
static void Main(string[] args)
{
Console.WriteLine("Starting foo...");
Thread.Sleep(1000); // hold console for a second on the screen
MinimizeConsoleWindow();
Console.ReadKey();
}

Related

WindowsAccessBridge for Java Automation using C#

I try to automate an java application using WindowsAccessBridge.dll.
I can get the window handle but calling the function isJavaWindow(System.IntPtr hWnd) always return false
Please find my code below:
static void Main()
{
System.Int32 vmID = 0;
System.Int64 _acParent = 0;
string WndName = "GLOBUS EDU";
string ClassName = "SunAwtFrame";
Windows_run();
System.IntPtr hWnd = System.IntPtr.Zero;
hWnd = (System.IntPtr)FindWindow(ClassName, WndName);
bool Found = isJavaWindow(hWnd);
if (!Found) { throw new System.Exception("ERROR: Unable to find window by classname " + ClassName + " and " + WndName + "!"); }
System.Console.WriteLine("Application is finished. Press ENTER to exit...");
System.Console.ReadKey();
}
Interop:
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
[System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
private extern static bool getAccessibleContextFromHWNDFct(System.IntPtr hwnd, out System.Int32 vmID, out System.Int32 _acParent);
private static bool getAccesibleContextFromHWND(System.IntPtr hWnd, out System.Int32 vmID, out System.Int64 acParent)
{
System.Int32 ac = -1;
bool retVal = false;
getAccessibleContextFromHWNDFct(hWnd, out vmID, out ac);
acParent = ac;
return retVal;
}
[System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
private extern static bool getAccessibleContextInfo(int vmID, System.IntPtr ac, out AccessibleContextInfo textInfo);
[System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
private extern static void Windows_run();
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
private static extern System.IntPtr FindWindow(string lpClassName, string lpWindowName);
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern System.IntPtr FindWindowByCaptionFct(System.IntPtr ZeroOnly, string lpWindowName);
private static System.IntPtr FindWindowByCaption(string WindowTitle) { return FindWindowByCaptionFct(System.IntPtr.Zero, WindowTitle); }
[System.Runtime.InteropServices.DllImport("WindowsAccessBridge-64.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
private extern static System.Boolean isJavaWindow(System.IntPtr hwnd);
The function FindWindowis working perfect and I'm getting the window handle also Spy++ shows me. The classname is SunAwtFrameas Spy++ says.
My Java applications runs in 64 bit but I tried all the Libraries (-32, -64) and also switched in the VS Configuration Manager from x86 to x64 and back.
The AccessBridge itself is working well - Java-Monkey-64.exe can spy my running java application.
Does anybody has an idea, why this is not working?
Regards,
Jan
I have been fighting with your problem in few days.
i created a program that enumerate window that is java application(of course write on console application), and catch same problem like yours.
then, i rewrite it on WPF application,enumerate all window, then recognize that: besides the normal window, i see a strange window named: "java access bridge", and the problem is clearly:
the Windows_run function need to have an active windows message pump.
another way, you must putting it on the constructor of a WPF application or something same that.
if (result != FALSE) {
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
shutdownAccessBridge();
}
code in Java Monkey application.
After create a hidden window, it performs a PostMessage with a registered message. The JVM side of the access bridge responds to this message, and posts back another message to the window that was created. As such, they communicate by that way.
and more, you only can call JAB functions after the message pump can process messages.
that is reason why the java monkey need to use call back for it's business.
Pass null for class name as in the below code:
IntPtr hWnd = FindWindow(null, "GLOBUS EDU"); //cast to IntPtr is redundant
bool Found = isJavaWindow(hWnd);
Reference is here on Pinvoke documentation, and it works for me!

Delay Sleep or Power Off mode to execute a method c#

I am using these system notifications to detect a power off or power on event for windows. Now I am trying to delay power off event and execute one function before that So how is that possible.
[DllImport(#"User32", EntryPoint = "RegisterPowerSettingNotification",
CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr RegisterPowerSettingNotification(
IntPtr hRecipient,
ref Guid PowerSettingGuid,
Int32 Flags);
[DllImport(#"User32", EntryPoint = "UnregisterPowerSettingNotification",
CallingConvention = CallingConvention.StdCall)]
private static extern bool UnregisterPowerSettingNotification(
IntPtr handle);

Using kernel32 CreateThread/TerminateThread inside Azure Worker Role

I have this code that I need to use, but what holds me back is that here it says that TerminateThread Applies to: desktop apps only.
I wonder if I can use this code inside azure Worker role, specifically inside waiishost.exe process that I use to run the Worker thread in?
[DllImport("Library.dll")]
public static extern void InfiniteLoop();
[DllImport("kernel32")]
private static extern int CreateThread(
IntPtr lpThreadAttributes,
UInt32 dwStackSize,
IntPtr lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
UInt32 lpThreadId
);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern int TerminateThread(int hThread);
[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetLastError();
private delegate int InvokeInfiniteLoop(IntPtr args);
static void Main(string[] args)
{
InvokeInfiniteLoop invokeInfiniteLoop = (args1) =>
{
InfiniteLoop();
return 0;
};
IntPtr infiniteLoopPtr = Marshal.GetFunctionPointerForDelegate(invokeInfiniteLoop);
int handle = CreateThread(IntPtr.Zero, 0, infiniteLoopPtr, IntPtr.Zero, 0, 0);
Thread.Sleep(TimeSpan.FromSeconds(5));
int terminated = TerminateThread(handle);
Console.WriteLine(terminated);
}
EDIT:
After further research looks like(as I suspected from the beginning) that this workaround is completely wrong. Creating and Terminating the unmanaged code will leak the stack. I will have to create a separate executable that will be terminated by Process.Kill();
The "Applies to: desktop apps only" refers to the difference between Windows 8 Desktop application and Windows 8 Metro applications.

Find handle of a ActiveX user control inside IE

How can I programatically find the handle of a user control in a webpage running on IE?
I'm able to find it using Spy++ but since the handle keeps changing I'm stuck.
I've been trying using FindWindow() but no luck :( I also wonder if I am doing something wrong or it simply only work for Windows...
Thanks in advance,
Zubrowka
I had a similar problem finding a PDF ActiveX Control inside a IE control in WPF.
To overcome the problem I used the EnumChildWindows API to find the correct child window and thus get its handle.
I'll include as much code as I can.
private static IntPtr FindPdfControlWindow(IntPtr parentHandle)
{
IntPtr result = IntPtr.Zero;
IntPtr matchPointer = IntPtr.Zero;
try
{
//allocate unmanaged memory for the result of the callback delegate
matchPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)));
Marshal.WriteIntPtr(matchPointer, IntPtr.Zero)
//instantiate the delegate and pass to the API
NativeMethods.EnumWindowProc windowChecker = CheckForPdfControlWindow;
if (!NativeMethods.EnumChildWindows(parentHandle,
windowChecker,
matchPointer))
}
finally
{
if (matchPointer != IntPtr.Zero) Marshal.FreeHGlobal(matchPointer);
}
return result;
}
private static bool CheckForPdfControlWindow(IntPtr handle,
IntPtr matchPointer)
{
int captionLength = NativeMehtods.GetWindowTextLength(handle);
if (captionLength > 0)
{
StringBuilder buffer = new StringBuilder(captionLength + 1);
NativeMethods.GetWindowText(handle, buffer, buffer.Capacity);
if (buffer.ToString().Contains("Adobe"))
{
Marhsal.WriteIntPtr(matchPointer, handle)
return false;
}
}
return true;
}
private static class NativeMethods
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool EnumChildWindows(IntPtr window,
EnumWindowProc callback,
IntPtr i);
internal delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSer.Auto)]
internal static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
internal static extern int GetWindowText(IntPtr hWnd,
StringBuilder lpString,
int nMaxCount);
}
transcribed in a rush so I hope it is both helpful and accurate.
If the ActiveX control is windowed, then you can query its IOleWindow interface to get the window handle.
Before you query interfaces from the ActiveX, you need to review the page's HTML to find a way to identify the activex in the document, such as element id.

am working in an application and I press key from keyboard, how can I capture that key (or string), including the source application's name, using C#?

i am working in an application and I press key from keyboard, how can I capture that key (or string), including the source application's name, using C#? i am working on a application, in this application i want to store keystrokes with source application for example if i working with notepad and i type " this is a pen" in notepad.
i have a list view with 3 column( application name, application path, window caption) now in application name column show the program which is open. now if notepad is open then it is showing in list view and i type some text in notepad. i want to store that text in a file which i typed in notepad, this is a console application but i wannna do it in windows application.
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
class InterceptKeys
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
public static void Main()
{
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
}
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
private delegate IntPtr LowLevelKeyboardProc(
int nCode, IntPtr wParam, IntPtr lParam);
private static IntPtr HookCallback(
int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
Console.WriteLine((Keys)vkCode);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
I don't think that this is best performed with C#, primarily because you will be needing to delve deeply within the Windows API, which obviates the basic presmise behind .NET in that it is platform independent.
As already stated by Anton you'll need to use Windows Hooks and process the WH_KEYBOARD type hook.
You probably would like to look at windows hooks.
Implementing what you want isn't a trivial task anyway because in order to get all keystrokes from all windows in the system you must get inside a window message processing mechanism of the operating system.
After all, I wouldn't suggest implementing windows hook that works under CLR. This may be disastrous to the whole OS in case you make a mistake and I'm not sure whether it is even possible.
It means either dig into C/C++ and write a global hook dll intercepting all keystrokes and implement interop with that dll or try to find a way of solving your problem without involving keystrokes capturing.
There are many managed wrappers for doing Global System Hooks for mouse and keyboard. The best implementation I've found is :
http://www.codeproject.com/KB/system/globalsystemhook.aspx
This will allow you to set a global keyboard hook and capture keystrokes in notepad. I've used it before and it's very easy to setup. Make sure you unhook when your app terminates.
Now to get the title of the window as you described in the second part of your requirements, you would need to get the current foreground window when you receive the keys from the hook. You can again use the Windows API functions GetForegroundWindow, and GetWindowText for that.
You could also get the process associated with the current foreground window by using Windows API GetWindowThreadProcessID and then using the managed framework System.Diagnostics.Process.GetProcessById() get all sorts of useful information about the source of the keystrokes.
You can look up information on how to implement all said Windows API Functions on pinvoke.net

Categories