C# : How to detect if screen reader is running? - c#

How to detect if screen reader is running (JAWS)?
As I understand in .NET 4 we can use AutomationInteropProvider.ClientsAreListening from System.Windows.Automation.Provider namespace, but what if I have to do it for .NET 2.0?
I tried to inspect ClientsAreListening source code, it calls external RawUiaClientsAreListening method from UIAutomationCore.dll library.
Do you have any ideas how to implement JAWS detection in .NET 2.0?

Use the SystemParametersInfo function passing a uiAction of SPI_GETSCREENREADER.
You will need to use P/Invoke for this, for example:
internal class UnsafeNativeMethods
{
public const uint SPI_GETSCREENREADER = 0x0046;
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref bool pvParam, uint fWinIni);
}
public static class ScreenReader
{
public static bool IsRunning
{
get
{
bool returnValue = false;
if (!UnsafeNativeMethods.SystemParametersInfo(UnsafeNativeMethods.SPI_GETSCREENREADER, 0, ref returnValue, 0))
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "error calling SystemParametersInfo");
}
return returnValue;
}
}
}
This is possibly better than using the ClientsAreListening property as this property appears to return true for any automation client, not just screen readers.
Also see:
Using SystemParametersInfo from C# (SPI_GETSCREENREADER SPI_SETSCREENREADER) (Stack Overflow)
INFO: How Clients and Servers Should Use SPI_SETSCREENREADER and SPI_GETSCREENREADER (Microsoft KB)
You should also listen for the WM_SETTINGCHANGE message to detect if a screen reader starts / stops running.
Update (in response to BrendanMcK's comments):
Although this is never explicitly documented in as many words, looking at the description of the flag I think the purpose of this flag is relatively clear:
Determines whether a screen reviewer utility is running. A screen reviewer utility directs textual information to an output device, such as a speech synthesizer or Braille display. When this flag is set, an application should provide textual information in situations where it would otherwise present the information graphically.
What this is saying is that applications set this flag whenever an application wishes the UI to behave as if a screen reader is running, regardless of whether or not that application is actually a screen reader or not.
Suitable things to do in response to this flag is to add text in order to "read" otherwise intuitive UI state to the user. If radical changes are needed to make your UI screen reader accessible then the chances are that your UI also isn't that intuitive to sigted users and could probably do with a re-think.

Related

OutputDebugString / System.Diagnostics.Debug.WriteLine and Debugger.IsAttached

I need to check if OutputDebugString / System.Diagnostics.Debug.WriteLine's output will go to never never land.
Seems like OutputDebugString is a native method while System.Diagnostics.Debug.WriteLine is writing to internal trace listeners.
Is Debugger.IsAttached a sufficient check for this?
Debugger.IsAttached doesn't seem to pick up if something like DebugView is running. I need to be able to check if ANYTHING will see output from OutputDebugString / System.Diagnostics.Debug.WriteLine.
If you are willing to get your hands dirty and use some native stuff you can achieve this. You'll need to use P/Invoke.
OutputDebugString, as you can read here, is based on 4 kernel objects. Mutex named DBWinMutex, a shared memory DBWIN_BUFFER and two events (DBWIN_BUFFER_READY and DBWIN_DATA_READY) as they wrote in the article - we can't relay on the mutex as it exists all the time. But we could check if the shared section is created.
If we import OpenFileMapping to our project from pinvoke.net
static class NativeFunctions
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr OpenFileMapping(
uint dwDesiredAccess,
bool bInheritHandle,
string lpName);
}
Then we can check if the section is created or not and based on that decide whether something is listening.
Writing this simple program
public const int FILE_MAP_READ = 0x0004;
static void Main(string[] args)
{
if (NativeFunctions.OpenFileMapping(FILE_MAP_READ, false, "DBWIN_BUFFER") != IntPtr.Zero)
{
Log("Someone is listening");
}
else
{
Log("I am here alone");
}
}
private static void Log(string log)
{
Debug.WriteLine(log);
Console.WriteLine(log);
}
When running without DebugView we get "I'm here alone"
and with the tool
Additionally to clarify the things ".. while System.Diagnostics.Debug.WriteLine is writing to internal trace listeners." Debug.WriteLine will also write to the same place as OutputDebugString but only if VS is not attached - otherwise VS will capture the log and post to its Output window.

Is processes threads (or whole process) suspended

I would like to check if the processes' threads (the whole process) are suspended.
I'm obtaining each process thread by this code:
var threads = Proc.Threads;
for (int x = 0; x < threads.Count; x++) {
var thread = threads[x];
However System.Diagnostics.ThreadState doesn't contain Suspended, but System.Threading.ThreadState does. How do I convert System.Diagnostics.ThreadState to System.Threading.ThreadState, or is it some other method to check it? I'm not trying to suspend/resume them, just I want to know how Process hacker/Process explorer does that.
Microsoft made a big mistake in .NET version 1.0, they added the Thread.Suspend() and Resume() methods. Those methods were widely abused, programmers used them to implement thread synchronization. For which they are entirely inappropriate. Problem was that it usually worked. But call Suspend() at an unlucky time and you'll freeze a thread while it is buried inside a Windows call, holding a global lock. And causing the entire program to deadlock.
It was not the only design mistake they made, the Synchronized method on the collection classes was quite a disaster as well. Widely misinterpreted as "returns a thread-safe collection".
Live and learn, this all got fixed in .NET 2.0. One big overhaul was that a Thread may not necessarily be an operating system thread anymore, that never actually got implemented. But explains why there are two ThreadState enumerations, one for Thread (the .NET version) and another for ProcessThread (the operating system version). And they closed the loophole on programmers abusing Suspend/Resume, the methods were declared obsolete. And they closed the backdoor as well, you can't find out from ProcessThread that a thread is suspended.
Feature, not a bug. Don't make the same mistake, knowing that a thread is suspended is useless knowledge, it may well not be suspended anymore a microsecond later.
This will help someone.
Process proc = Process.GetProcessById(31448);
if(proc.Threads[0].WaitReason == ThreadWaitReason.Suspended)
{
//process is suspended
}
An operating system thread isn't the same as a .Net thread. Process.Threads returns OS threads, each of which may or may not correspond to a .Net thread.
You can look at ProcessThread.WaitReason, but it doesn't correspond to .Net wait states
You could improperly use SuspendThread or Wow64SuspendThread to find out if it was suspended, then use ResumeThread to restore the situation.
SuspendThread return: "If the function succeeds, the return value is the thread's previous suspend count;"
Declarations:
[Flags] public enum ThreadAccess : int {
TERMINATE = (0x0001),
SUSPEND_RESUME = (0x0002),
GET_CONTEXT = (0x0008),
SET_CONTEXT = (0x0010),
SET_INFORMATION = (0x0020),
QUERY_INFORMATION = (0x0040),
SET_THREAD_TOKEN = (0x0080),
IMPERSONATE = (0x0100),
DIRECT_IMPERSONATION = (0x0200)}
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(
ThreadAccess dwDesiredAccess,
bool bInheritHandle,
uint dwThreadId);
[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
[DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
(Wow64SuspendThread link hidden because i need 10 reputation to put over 2 links = ht.tps://msdn.microsoft.com/it-it/library/windows/desktop/ms687400(v=vs.85).aspx)

C# SendKeys Wait for Program to Load before sending

So long story short, I am trying to automate some things when my computer boots up. I thought I'd write an C# console application to do this and then add it to a schedule task in windows to be executed on bootup. My problem is with one program, it requires a password and has no options to open via the command line. Thus it must be entered manually. My thought was to retrieve my password from a KeePass database and use SendKeys to enter the password and login to the program. The problem I'm having is the time it takes to load; I have no way of detecting when the GUI interface has loaded and is ready for my SendKeys. Is there any way to detect this? I'm assuming all I have to work with is the "Process" class since thats what I used to run the program. Also note that when I run the executable using Process.Start(), the program creates another process for logging in, but it has no associated window that I can see using Windows API calls.
Okay that was long, I can re-cap...
Problem:
From C# detecting when a third party program has loaded (i.e. the splash screen is gone and GUI is ready for user interaction - meaning I can't just rely on if the Process is running or not).
Also, no command line options for the third party program, or I would just run it with the password as an argument.
Goal:
To use SendKeys in order to automate entering a password, but my program must wait for the third party application to finish loading.
Notes:
Using C# .NET 3.5 Console Application
NOT detecting load for my own form but a third party otherwise this would be easy (i.e. form_loaded event...)
Thank you for looking at my question, if you want any more details or anything let me know.
UPDATE:
Problem solved!
The two answers I received combined to give me the solution I wanted. So if anyone comes across this later, here is what I did to make it work.
So this program automates a login for some client software that you must login to. My problem was that the software offered not option or documentation for command line prameters which many other programs offer so you can login with a keyfile or something. This program also disabled copy and paste so the password HAS to be typed in manually, which is a big pain if you use passwords like I do, long complicated ones with no patterns. So I wrote this program for my benefit as well others at work; I just schedule it to run at logon to my windows machine and it opens the client software and performs login automatically.
//
// IMPORTANT Windows API imports....
//
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint procId);
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
// When I get to this point in my code, I already had the password and window title...
string password = "password";
string title = "window title";
// This gets a handle to the window I want where "title" is the text in the title
// bar of the window as a string.
// This is a Windows API function that must be imported by DLLImport
// I had to get the handle this way because all I knew about the third party
// window was the title, not the process name or anything...
IntPtr hWnd = FindWindowEx(IntPtr.Zero, IntPtr.Zero, null, title);
// Now that I have a handle to the login window I used another windows API
// call to get the process ID.
// This windows API call gives me the Process ID as an out parameter and returns
// the thread ID of the window. I don't use the thread it, but maybe you can...
uint loginWindowProcId;
uint loginWindowThreadId = GetWindowThreadProcessId(hWnd, out loginWindowProcId);
// now I can just use .NET to find the Process for me...
Process loginWindowProcess = null;
if (0 != loginWindowProcId)
{
// get the process object
loginWindowProcess = Process.GetProcessById((int)loginWindowProcId);
// This right here is why I wanted the Process structure. It takes a
// little while for the client software to load and be ready. So here
// you wait for the window to be idle so you know it has loaded and can
// receive user input, or in this case keys from "SendKeys".
loginWindowProcess.WaitForInputIdle();
// I use yet another windows API call to make sure that the login window
// is currently in the foreground. This ensures that the keys are sent
// to the right window. Use the handle that we started with.
SetForegroundWindow(hWnd);
// Now send the password to the window. In my case, the user name is
// always there from my windows credentials. So normally I would type in the
// password and press ENTER to login. But here I'll use SendKeys to mimic my
// behavior.
SendKeys.SendWait(password); // send password string
SendKeys.SendWait("{ENTER}"); // send ENTER key
// Now the client should be logging in for you! : )
// IMPORTANT NOTE
// If you are using a console application like I am, you must add a reference to
// System.Windows.Forms to your project and put "using System.Windows.Forms;" in
// your code. This is required to use the "SendKeys" function.
//
// Also this code is just for my testing (quick and dirty), you will want to write
// more checks and catch errors and such. You should probably give the
// WaitForInputIdle a timeout etc...
}
You can check with Process.WaitForInputIdle after you start a process, and wait until is fully started, here is the simple example :
http://msdn.microsoft.com/en-us/library/xb73d10t%28v=vs.71%29.aspx
Try looking at that: http://www.acoolsip.com/a-cool-blog/science-and-technology/151-c-sending-commands-to-independent-windows.html
you can check if the window is shown (using the link) and then sending messages (also on the link)

Windows Mobile 6.5 SndPlayAsync - C# wrapper?

I'm implementing mp3 playback on Windows Mobile 6.5. I need to use SndPlayAsync API function since I don't want to block calling thread until the file is played (SndPlaySync blocks until the audio file is playing). Unfortunately the SndPlayAsync method takes sound handle instead of sound file path as parameter so there's a need to open the handle before and release of it after playback. The problem is that I don't have any information about the playback completion in this API. Did anybody use a C# wrapper for this API? Where can I get one? I've looked up OPENNETCF but they seem not to support this API.
Regards
You have to call SndOpen first to get the handle. Looking at the docs, the declarations would be something along these lines:
[DllImport("coredll", SetLastError=true)]
public static extern int SndOpen(string fileName, out IntPtr handle);
[DllImport("coredll", SetLastError=true)]
public static extern int SndPlayAsync (IntPtr handle, int flags);
[DllImport("coredll", SetLastError=true)]
public static extern int SndClose(IntPtr handle);
So you'd use something like this to call it:
IntPtr handle;
var result = SndOpen("myfile.mp3", out handle);
if(result == 0) SndPlayAsync(handle, 0);
...
SndClose(handle);
If you are using .NET CF there is no reason to create a wrapper, you can just use the System.Media.SoundPlayer class to handle it. There are several options including PlaySync which will play the sound synchronously.
For instance:
string path = "\\Program Files\\SNAP.App.CE\\Content\\5LongLow.wav";
System.Media.SoundPlayer player = new System.Media.SoundPlayer(path);
player.PlaySync();
You can also put it in a separate thread if you don't want to block the UI thread.
You can use SndGetWaitHandle to get a handle to an event which will be signaled when the sound is finished playing. You can use the WaitForSingleObject API to wait or test if the event has been set.

How do I prevent print screen

I have a requirement that an application I am working on prevent the user from being able to easily capture the contents of the screen.
I have communicated that there is no feasible way to completely prevent this from happening, but I'm looking for methods to introduce some hurdles to the process.
I'm using C#/.NET 2.0 and WinForms
You can't.
The best you can do is render to a hardware accelerated device on an overlay, similar to what video players used to do. Basically, you paint your entire window blue, and render your graphics onto the video card, and internally the video card will replace the blue with the graphics. The downside to this is you have to give up using winforms controls, and I don't know of any way to do this with .NET easily. I think if you use DirectShow.NET, one of their samples is putting your own graphics into a stream.
Even after doing all of that, it's still possible to get a screenshot. Just take a picture of the screen with a digital camera.
From here:
A. Windows implements Print Screen using a registered hotkey. Windows
uses the predefined hotkeys IDHOT_SNAPDESKTOP and IDHOT_SNAPWINDOW to
handle Print Screen. These correspond to Print Screen, which captures
the entire screen, and Alt+Print Screen, which captures only the
active window. To disable these functions all you have to do is
register the hotkeys, which causes Windows to send your app a
WM_HOTKEY message when the user presses either hotkey. Your
implementation can ignore the message to bypass the default
screen-capture behavior. A good place to do it is in your mainframe
class.
FWIW, it is possible. Here's some code:
This would be a dll that you create, then call the HookKeyboard method from your application. I've tested it and it works. Granted, if someone takes a picture with a camera it can't help, but, point made. NYAH!
namespace KeyboardHook
{
public class Hooker
{
[StructLayout(LayoutKind.Sequential)]
public struct KBDLLHOOKSTRUCT
{
public int vkCode;
public int scanCode;
public int flags;
public int time
;
public int extraInfo;
}
public delegate int HookProc(int nCode, int wParam, IntPtr ptrKBDLLHOOKSTRUCT);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc callBack, IntPtr hMod, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern int CallNextHookEx(IntPtr hhk, int nCode, int wParam, IntPtr lParam);
private static IntPtr kbh_Handle;
private static HookProc kbh_HookProc;
private const int VK_SNAPSHOT = 0x2C;
private const int WM_KEYDOWN = 0x0100;
private const int WM_SYSKEYDOWN = 0x0104;
private const int WH_KEYBOARD_LL = 13;
private static int LowLevelKeyboardProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode < 0)
{
CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
return 0;
}
if (wParam == WM_KEYDOWN)
{
IntPtr kbdll = lParam;
KBDLLHOOKSTRUCT kbdllstruct = (KBDLLHOOKSTRUCT)Marshal.PtrToStructure(kbdll, typeof(KBDLLHOOKSTRUCT));
if (kbdllstruct.vkCode == VK_SNAPSHOT)
return -1;
}
return CallNextHookEx(kbh_Handle, nCode, wParam, lParam);
}
public static void HookKeyboard()
{
try
{
kbh_HookProc = LowLevelKeyboardProc;
kbh_Handle = SetWindowsHookEx(WH_KEYBOARD_LL, kbh_HookProc, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
if (kbh_Handle != IntPtr.Zero)
System.Diagnostics.Debug.WriteLine(String.Format("It worked! HookHandle: {0}", kbh_Handle));
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(String.Format("ERROR: {0}", ex.Message));
}
}
}
}
You can try using IpcProtectWindow provided in msipc.dll.
[DllImport("msipc.dll", SetLastError = false, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
internal static extern int IpcProtectWindow([In] IntPtr hwnd);
Download the SDK from Microsoft
Call the function above and provide the handle of the form you would like to protect. (Form.Handle property)
You'll have two cases here that you need to worry about. One, when your window/application has focus, the other when it doesn't have focus.
When it doesn't have focus, there's not a whole lot you can do, i.e. if the user clicks off of your app and onto the desktop, keys aren't sent to your app so you'll never see them. In that case, you can minimize to the tray when your app loses focus (or, perhaps, place a "blank" panel over the form to prevent users from seeing anything on it which will also prevent a print-screen from being useful).
In the other case, when you have focus, capture keystrokes and examine them. If the Alt key is down and the PrintScreen key is down, reset the value so that a print-screen doesn't occur. (Come to think of it, that may not work. I'd need to test it to be sure.)
You could look into what movie players do. I believe they render directly to a hardware surface (via DirectX). I suspect that you'd need to do this.
This doesn't really answer the questions, but keep in mind that there exists tools to capture screen, and that a simple camera breaks everything.
I mean ok you "have to", but I would (but I'm young and still student, so I don't know much about what can be said) answer that this is just stupid.
Check out the new tech - sivizion.com, they prevent print screen all together - no way to bypass it. If anyone will figure out a way how to hack it, please post here, I couldn't. I think they also license their tech, not sure, check it out.
Well, you could try capturing the button, but I'm not sure how well that will work.
One thing that always annoyed me was that whenever I played a movie, it would never take screenshots of it. If you can render through a separate context, it would make it really annoying to take a picture of it. Perhaps you can send your screen output through something like that?
There are applications that can capture the screen from OpenGL and DirectX apps ! (depending (they are used for recording game movies)
ps. windows aero is DirectX
http://www.fraps.com/
i think thats the application
You can make any casual Print Screen useless using Visual Cryptography and taking advantage of retinal persistence (see this article for details, and bit.ly/vcrypto for a web demo).
The idea is to alternate at high frequency between two or more random noise images, that will combine through persistence of vision to reveal the content. A screen capture will only grab one image, with meaningless random noise.
This comes at the cost of flickering and inducing user headaches, can be defeated by a camera taking a picture of the screen, or by a less casual user that knows photoshop, but will defeat any kind of casual screen capture or frame grabbing.
Might occasionally be useful, in an academic meaning of the term!
It is too late but there is a quick work around,
Simply use it in MDI form
Set TopMost Property of form True, then write below event
private void frmMDI_Deactivate(object sender, EventArgs e){Clipboard.Clear();}
after taking print screen user have to minimize the application, the moment user minimize the app, we are clearing clipboard.
you can use this in logout function or when screen move or resize or any other form event as required :)
Snipping tool also can't copy screens by this if TopMost Property is true.
Yes we can't stop user from capturing screen from external device like phone or cam.
In windows form application, Use this code in form keyup event,
if (e.KeyCode == Keys.PrintScreen)
{
Clipboard.Clear();
}
Form keypreview should be TRUE
Microsoft has been developed an API named SetWindowDisplayAffinity to support the window content protection. This feature enables applications to protect application content from being captured or copied through a specific set of public operating system features and APIs
SetWindowDisplayAffinity(hWnd, WDA_MONITOR);
I solved it using a Timer object and Clipboard.Clear() method.
First add a Timer to your main form with Interval=1 (Very fast), then add the following code in its event:
Clipboard.Clear();

Categories

Resources