I wrote a desktop alerts application that sends a variety of notifications to all clients that are currently logged in. The app lives in the system tray, with a right-click menu to select an alert. When an alert is sent, a pop-up displays on each client's desktop with the type of alert. The pop-up is a simple Window class:
alertWindow.showDialog();
Our PC's have a policy on them to automatically lock the screen after 10 minutes of inactivity. What I'd like to know is if there's any way to have the alerts display while the screen is locked. Any help would be appreciated.
You could put the required information into an image and then change the lock screen background with the Windows.System.UserProfile.Lockscreen class in the Windows Runtime APIs.
Windows.System.UserProfile.LockScreen.SetImageFileAsync(file);
The lockscreen itself is de-facto a different user session which runs with winlogon privileges.
i've done such thing under window 7 quite a while ago, but cant recall the details right now.
The general approach is:
open winlogon process handle
copy access token from process
create a new process with the just copied access token
create your windows on the lockscreen
it's a pretty hacky approach using many api calls but the only one that works.
As soon as I'm back at my home-pc i can see if i can find some details on how i exactly have done it.
[Edit]
I now had the chance to review the code and i have to say i'ts a little more complicated than outlined.
Key element is, that you need a service (which i wrote in C++) which runs with system permissions.
This service has to copy the impersonation token from the winlogon process and after that, launch a new process with that new token.
API functions for reference
GetTokenInformation
OpenProcessToken
DuplicateTokenEx
AdjustTokenPrivileges
[/Edit]
Related
I would like to display an UI that interacts with user on pre-logon screen (the screen where users usually enter their username/password)
I read that the architecture of Winlogon packages has changed and will not help me in Windows 7.
I was referred to use WTS functions, however I am still not clear on how to use them or which ones.
I already created a Service which brings up a notepad.exe (for now), however I need to trigger this Service when user is in pre-logon screen. I am not sure what or how to implement that.
what you are trying to do is use Windows Interactive Logon Architecture
Windows Vista examples here (Credential Providers)
Windows 7 technet article
There's a reason it's HARD to do this kind of thing. Programs are minions of users. Pre-logon, there's (typically) no user to be a minion of. Its a security thing.
Just have your service fire off when a user logs in.
One way to get UI to show up without anybody logged in is to have a login screensaver. Your code (which could be .NET) would run after the timeout up until either you exit or somebody presses Ctrl-Alt-Del.
There are limits to what you can do as a login screensaver, but it may work for you.
From what I understand of your requirement, you want to display a custom user interface at the Credential Provider level. You can achieve this by one of the following approaches:
(1) Write a custom CP that includes your UI as a modal dialog in the SetSelected method of the credential : This approach will allow you to customize any UI. Once the modal window gets dismissed, the actual password CP gets built (assuming you wrap the default password CP).
(2) Launch the application from a Windows Service: This approach will not stop the providers from getting initialized. Basically, the Windows Service is used to launch a process in Winsta0\Winlogon desktop. You can access the process launched using Alt+TAB. Here's the basic steps you would need to use:
WTSGetActiveConsoleSessionId to get the active session ID
WTSQueryUserToken() to get the winlogon pid
DuplicateTokenEx to duplicate the token
Adjust the token privileges by calling AdjustTokenPrivileges
CreateProcessAsUser with lpDesktop as Winsta0\Winlogon
I have used both approaches. The first one is used to introduce more secure login. The second is used to launch remote access tools, cmd prompt etc.
I wonder is it possible to run my application before login on windows.? Its actually a WinForm application(Preferably other than Windows service).
I mean my application must be running even before log in and it should sit on System Tray from which I can "show" or open Interface for user.
To have:
Something happen between system startup and user login
An icon in the notification area for users to interact with
You must break your application up into two separate components. One of these will be a WinForms/WPF application which provides the notification area icon and allows the user to interact with it. The other will be a Windows Service, or possibly a scheduled task.
Once you've done this, the windows service can focus on doing whatever needs to be done prior to logon and the notification area application can assume responsibility for showing the results, or whatever else to the end user.
To answer the question you posed in comments regarding reading data from the Event Log, yes this is possible. There are other questions on here which will give you that particular answer:
read the windows event log by particular Source
Read event log in C#
This MS article might help but it is a bit old:
http://support.microsoft.com/kb/142905
Hopefully it'll put you on the right tracks though.
I think, it doesn't make sense, to acquire user input before a user has logged into the system. So, if the application needs input from a user, why start it before the use has logged in? If the application just starts some background work, than you should use a windows service, as this is the prefered way in windows.
Type in run gpedit.msc, for Group Policy,
There you can set start up script.
Application will launch before Windows Login,
Step to produce :-
Start --> Run --> gpedit.msc --> Local Computer Policy --> Windows Settings --> Script (Startup/ShutDown),
Add you .exe
It will launch Before login.
Do not try more in Group Policy, it may happen harmful for System
By Programmatic logic,
Try with registry key
this value is updating in registry,
by our program we can update directly registry then we can call application
You can schedule any application to be run when computer is powered on using Windows Task Scheduler. There is a corresponding option there.
But why would you need this? You should use a service for this.
I have created a .NET Windows application in C#. I want to execute this application when the system becomes idle for sometime. The application is a user login application, i.e. when system becomes idle for sometime, a login page appears where the user logins with his username and password. Then only the user can continue using the system.
How can I make it work out? Please help as I am new in Windows applications.
I thought to run the application as a Windows service. I managed to run the application on Windows service start. But how can I trigger the app to run only when system goes to idle in Windows service? I also need to start the timer after the user logins to check idle time again. Please provide some code examples.
The system already comes with such functionality. On the screen saver configuration page you simply check the box titled "On resume, display logon screen". It can be configured with group policy.
There's absolutely no point re-implementing this.
How about:
Start your form hidden
Get the system idle time
Show your window.
My aim is to create a login form where the login form comes when the system goes idle.This form contains username/ password and comment box where user have to provide reason for why system has goes to idle state.(ie if user left for a meeting or a break,he/she should provide details about it).this should be a window application which i managed to make.
Now i have to make this application run when ever system goes idle and the user can use only when login through this.So windows service is a option to run a program when the system starts and it can be managed well through service. So i made a window service which mange to run the application when the service start.
Now i have mange the window service to call this win app every time system goes idle. what possible ways can i make it work through window service.
I have already mention the above question in a previous post here
please help...
This is the kind of app that users hate with a passion, nobody likes a machine forcing them to do things. They'll try everything they can to get rid of it or sabotage it. Any data it collects is junk. Vista partly solved the problem, services cannot do this anymore.
Don't waste your time on it.
I'm running a process from inside a windows service using
ProcessStartInfo processStartInfo = new ....
Process.Start(processStartInfo);
The problem is, if I run service under local system account, it runs alright, but it doesn't show the programs' window.
I've tried to put user credentials in service properties, but then 'Allow service to interact with desktop' checkbox becomes disable.
I really need to run the app calling it from service, and I really need to see the app's window.
Help me please.
UPD. Well, you use overloaded version of Process.Start what takes username, password and domain - it will pull the program to the desktop. But now it starts the app under one credentials but shows that on a different user's desktop. How come?
UPD2: I have an idea! I can use psexec.exe from Sysinternals Suite. But the problem is I need to start that thing silently "as administrator". And I don't know how.
I mean even if you're already have admin rights, sometimes you have to manually say "run as administrator", confirm UAC and only after that you're ready to go. I don't know how silently run something without bringing UAC thing....
UPD3: Dear Lord. I've got that thing! Finally.
Ok. In the beginning the problem was indeed in session 0 isolation thing. So I needed to build a middle app that can be started from the service and then, that app in its turn suppose to start my application through RPC and bring it to a desktop. Instead of building middle layer app I decided to use psexec tool (anyway it works exactly the way I need - through RPC).
And when I tried to use that tool under LOCAL SYSTEM account it didn't work for some reason. And then I realized - the reason is damn EULA popup dialog that MS put in every single pstool, and it was impossible to click the button to confirm dialog under local system account.
So the solution is to create a key in the registry HKU.DEFAULT\Software\Sysinternals\PsExec with DWORD value EulaAccepted = 1
Hooray, now it works!
BUT! Now I need to bring the program to the currently logged user's screen. To do that I'm gonna need the session id!
So the question is: How to get currently logged user's session id? And what happens if there's no one logged yet? What session id that would be?
UPD4: That's it! I got that one!
[DllImport("Kernel32.dll", EntryPoint = "WTSGetActiveConsoleSessionId")]
public static extern int WTSGetActiveConsoleSessionId();
Thank you guys!
You can get the active console session id using WTSGetActiveConsoleSessionId (from the terminal services API). You can only use it for WinXP/Win2K3 or higher, but that should be fine, as you can hard code 0 for the session id on Win2K or earlier. Here is the PInvoke signature for it:
[DllImport("Kernel32.dll", SetLastError = true)]
[return:MarshalAs(UnmanagedType.U4)]
public static extern int WTSGetActiveConsoleSessionId ( );
As far as launching a process in the user's session, you can refer to the answer I gave here. It basically involves callling four API's; WTSGEtConsoleSessionId, WTSQueryUserToken, DuplicateTokenEx, then CreateProcessAsUser, and it will work on any machine running WinXP/Win2K3 or higher.
One solution would be to have a third process act as an intermediary, and tell it to launch apps via RPC/Named pipes.
Processes:
Windows service
Intermediary application
The app you want to run
The shim creates a communication endpoint (named pipe, WCF endpoint) and listens on it. When it gets a message to go ahead, it launches the app you want to run.
Then, when the Windows service wants to launch an app, it finds and opens the endpoint (named pipe, WCF endpoint), and sends the message to launch the app. Then the intermediary application takes care of the process launching business, and doesn't have any of the limitations that the Windows service has.
Make this intermediary process start with logon, and you're good to go.
This is similar to how the Microsoft test agent/controller work when you need to run tests that interact with the desktop.
This can be done without an intermediate process, but it requires more than 500 lines of code to do. Basically, you want to launch your second process as the current logged on user. For Vista/7, this user will have their own winlogon process, while for XP, they will have an explorer process. You need to get the primary token, environment block, security attributes, and thread security attributes of that running process then call the Windows API function CreateProcessAsUser with all that information, making sure you select the correct window station as well (usually "WinSta0\Default"). This is all doable, but you might have a better time with the other suggestion of a second process and IPC.
If you are trying this on anything newer than WindowsXP this will not work. This is because of a new feature introduced in Vista / Windows 7 called Session 0 isolation. http://msdn.microsoft.com/en-us/library/bb756986.aspx You will not be able to get a app launched by a service to show up on the users desktop.