I'm trying to build an application that needs to lock down access to the PC while it is running. I need to make the app run topmost, in full screen mode, and ensure that alt-tabbing doesn't allow access to other apps or the taskbar.
So far I have set TopMost = true, WindowStyle = WindowStyle.None and WindowState = WindowState.Maximized which achieves most of what I need, but I still get instances where the taskbar becomes visible. I've tried to implement the LostFocus behaviour on the window, but that doesn't seem to give me the behaviour I need.
Can anyone point me in the direction I need to implement this behaviour, please?
Additional Info
Unfortunately, the nature of this project is such that we can't alter the client machines, and they are running a mix of XP, Vista and Win7. The PCs are not owned by us, but are to be used for delivery of content in as secure a manner as possible. The owners of the PCs are aware of the restrictions for running the software, and are happy for them to be "locked down" during execution of our application, but they cannot otherwise be altered.
Other ways
HakonB mentioned Scott Hanselman's BabySmash application, so I went looking for his way of handling the situation. As HakonB says, it isn't the cleanest method of handling lost focus, but it seems to work, or at least should do until I find a better solution. He uses a timer that fires every second, and fires off a call to user32.dll's SetForegroundWindow(IntPtr hWnd) method to grab focus, regardless of whether it has focus or not. Thanks for the heads-up, HakonB!
Take a look at Scott Hanselman's BabySmash. You can find the site at BabySmash
He had a couple of blog entries describing his work to make the application. It features a baby-safe application in kiosk mode.
You can find the project on Codeplex
Related
I've got an issue with the focus management in WinRT. The issue is specific for the application startup. Let me share the example of it:
If during the startup I change the focus (for instance I can start selecting some text in a browser), the runtime will decide that it doesn't need to show the application. The application is being started in a 'hidden mode'. It means that I do not see the UI, but I still can find it in process explorer.
So what I need here is to make the application be active in all possible cases. I tried to use several native functions such as ShowWindow, SetActiveWindow, SetForegroundWindow, but without any success.
I also noticed that any WinRT app is being started under WWAHOST.exe and mainwindowhandle is 0. The app shows up if I use 'Switch to' option in Process Explorer context menu.
WinRT applications are sandboxed and have very little control on the way the OS handles them, and almost no way to affect the behavior of other applications running on the same host. What I would suggest then is for you to design your application in such a way that it shows some UI as early as possible, then asynchronously you can load any other resources that your application may need.
I am writing an application in c# to lock or freeze all programs untill user enters a value in the app's textbox and clicks ok.
The purpose of the app would be to get people to enter their time.
As far as I know you can set it to top most but they can end the app with task manager so am stuck here..
formName.TopMost = true;
Any help would be appreciated
Yes, that's correct. The Windows operating system allows multiple programs to run at one time. What you're experiencing is entirely by design.
If I remember correctly, the TopMost property applies only to windows in your process, and as you mention, it's all quite irrelevant: the user can still kill your application using the Task Manager.
There's no legitimate way of getting around that. It's not a "limitation", it's a feature. Any app that prevents itself from being closed by the Task Manager is treading dangerously closely on the category of software that we call malware. Nothing good can come out of pursuits like this.
Relevant reading: The arms race between programs and users
Perhaps a good compromise solution is to make your window/form actually top-most and disable the Close button so that the user knows they shouldn't try and close it. This is almost always enough to stop a user that is not determined to end your application by any means necessary, and that's about all you should ever be concerned with.
See the sample code here for how to make your window/form always appear on top of other running applications by setting the WS_EX_TOPMOST flag or toggling HWND_TOPMOST.
I've also already written a detailed answer here about disabling the Close button the correct way by setting the CS_NOCLOSE class style.
How to show messagebox dialog which will not allow user to switch to another window as long as that dialog is not closed like shutdown dialog in windows XP using VB.NET or C# windows application
You can't easily prevent interaction with other applications even from a system-modal message box.
One option is to display a large transparent window behind your message box with the WS_EX_TOPMOST window style. That way it would appear that the other windows are interactive, but clicks would hit your transparent window instead.
You couldn't prevent Control+Alt+Delete though and you'd have to take extra steps to prevent Alt+Tab and such. Also other topmost windows could still compete for the top.
In other words, it's a pain to do and for good reason. As Raymond Chen would say, you may have the most awesome and important application in the world but if it were easy then all of the other applications that aren't as awesome and important as yours would be able to abuse it.
What you're looking for is called a system-modal dialog. This is in contrast to the more typical application-modal dialog, which only prevents the user from doing anything else in your application until they dismiss the dialog. A system-modal dialog extends this prohibition to the entire system and prevents the user from doing anything else at all with their computer until they've dismissed your dialog.
This was possible under 16-bit Windows (versions 3.x and earlier), but this functionality was removed when 32-bit Windows rolled onto the scene (as far back as Windows 95 and NT 3.5). Presumably, there were some vaguely more technical reasons that this capability was now denied to application programmers, but its absence also meant the end to widespread abuse of this feature by developers who thought their application was the only important thing the user could possibly be doing on their computer. (Some of those "vaguely more technical reasons" are related to better support for multitasking and the obsolescence of the "one program—one focus" paradigm.)
Raymond Chen answers the question definitively in a forum post made to this thread:
Win32 doesn't have system modal dialogs any more. All dialogs are modal to their owner.
If you want to simulate such functionality now (and it's highly recommended that you not do so, because it wasn't good programming practice before, and it's particularly alien to users now), you'll have to rely on a hack. This means your solution won't be fool-proof and could be easily bypassed by a knowledgeable or experienced user.
My recommendation is to seriously re-consider your need to prevent the user from switching to another application while a dialog box is visible in your application. System-modal dialogs are a contradiction with today's modern multitasking environments, and there are only extremely limited circumstances where they make sense. Most of those circumstances are limited to the operating system (the shutdown dialog from your example, UAC prompts from Windows Vista/7), rather than individual applications. See if you can't settle for the expected and less user-hostile application modal dialog instead, which you can get easily in C# and VB.NET using the ShowDialog method.
I have an idea to write a multimotor taskbar application in c# for windows xp. So, does anyone have any information how
to put a taskbar on the second
monitor,
to make it use windows styles,
to prevent aplications running on the
second monitor to appear in default
taskbar,
so on...
Any help would be ...helpful )))
You can P/Invoke SHAppBarMessage() to create a task bar. The APPBARDATA.hWnd you'll need could simply be the Handle of a Form class. Anything goes as far as what you display.
Getting the notifications you'll need to make the task bar display active windows is going to be a whole lot more difficult. You'll need to use the global WH_SHELL hook, set by SetWindowsHookEx() to receive the notifications you'll need. You cannot set this hook in C#, it requires an unmanaged DLL that you can inject into a process. You'll find crucial help in this project.
Getting the Windows taskbar to not do its normal job is going to be impossible unless you somehow find the undocumented information you'll need. Microsoft doesn't document this for a good reason, the taskbar is an important part of the way they innovate on the Windows look-and-feel. Quite visible in Win7. They don't want any code to take a dependency on this, they'd have a near-impossible job of keeping the next version of Windows compatible. I'd have to recommend you completely disable the Windows taskbar and replace it by your own.
What is the best and cleanest way to close a console application on windows mobile?
The application by default is invisible and you cannot see it in the running programs, which is great for running a background process, but sometimes the user might need to close it..
Exit Main. Seriously. If you need someone to be able to exit is manually, there needs to be some mechanism like a shell icon and menu or a program in the Programs folder of something. How else would the user even know it's running? Any one of those visual cues would then set a named system event, and inside your Console app you'd have something listening for the same event (likely a worker). When it gets set, you take the actions required to shut down.
How would a user be able to close it if the application is not visible in the UI?
That's a great question. I once spent a long time trying to figure this out. Of course, we are assuming you can not (easily) return from Main. The correct answer on the desktop is System.Environment.Exit; But that method is conveniently not supported on CF.
An apparent second option is Application.Exit. That is on CF, but only applies to WinForms, and is in fact not guaranteed to exit your application.
So, throw an unhandled exception. ;)
EDIT: To kill it programatically from another app, you can look at Process.GetProcessById, and Process.Kill. Both of these are available on CF. You will have to somehow let the "killer" app figure out the "victim"'s ID. More convenient methods like Process.GetProcessesByName are not available on CF.
This technique isn't that elegant, though, and there may be permissions issues.
You could also consider some kind of IPC (inter-process communication), perhaps one overviewed in this previous Windows Mobile answer.
I decided to to read a boolean (keep alive) in the config file and have another application set it to false when I want to exit.
Its not that responsive but at least I can exit cleanly..