I want to set up a system whereby anyone logged onto a machine on our local network can see what's on the screen of any other machine on the local network. This is part of a peer-monitoring programme, and is with the agreement of all users.
All machines are running Windows 7 or 10. Ideally, I would like it that someone using an iPad could also see the screens.
My initial thought was to install IIS on each machine, and have a web site that would capture the screen and return it on request. That way, a user at another machine could just browse to http://machinename/ and see the screenshots. This would work for desktop machines and iPads.
However, I discovered that you can't access the screen that way, so that idea is out. Similarly, it seems that a Windows service can't access the screen either.
What options do I have? I want something that can be installed once for all users, and show what's on the screen(s) attached to that machine.
Like a lot of similar questions out there, a simple solution requires just some basic understanding of how Windows session isolation works, detailed in posts like this.
As you want to capture screenshots, your code must run in the same user session. Then any sample code you find from search engines will work flawlessly.
Many existing screen capture solutions are built upon this simple approach, and usually have a Windows tray app that launches when a user logs in, which prepares the screen shots by calling the capture API.
You cannot use a Windows service or a web app on IIS to call the capture API, because they run in session 0, not that user session.
Behind the scene, other necessary components are there to dispatch the screen shots to a centralized backend server (so that they can then be sent to the monitoring device).
Note that for this part multiple approaches/architectures can be used, so I won't share too much to restrict your imagination.
Related
I am currently developing an integration between a web app and a windows application, where everything works fine on standard setups. However, introducing Citrix to the equation complicates everything quite a bit.
The current solution
At the moment we have a POC (proof of concept) running with custom Uri Scheme registration to a little exe we have developed, and listing active instances with Global Atom (using this trick to list search all entries). This way, we can see if an instance of our application is running. If it is, we call it via SendMessage, and if not, we start the application in a new process, and wait for it to be ready, for us to call it.
The issues introduced with Citrix
Now, when using Citrix Desktop Sessions, we do not suspect we will run into any issues, but with Application Sessions (AKA XenApp) the Citrix documentation states: "URL redirection works only for desktop sessions, not application sessions.", and we have therefor run into a brick wall with our implementation. So to sum up, we now have issues with accomplishing the following steps:
Registering a custom URI Scheme handler: That might not at all be supported. The way we use it now, it points to an application on disk, but the Application is installed on a server.
Detecting if an instance is running: We do not know if Global Atoms are even possible in this setup, and I have been unable to find any documentation on this.
Calling a XenApp window with SendMessage: When running the simplest XenApp configuration we could reproduce, we can inspect the hosting process and get the handle to our application, but the application never gets the message sent at it.
Solving it within the current solution scope
Can the above scenario be accomplished in a Citrix environment using Application Sessions? If so, how? The tests I have performed so far, appears to confirm my suspicions that it is simply not supported within this setup.
Solving it in similar fassion
The POC we have developed is simple and modular, and changing how instances are located and communicated with is easily implemented and made configureable to our clients specific setup. It will then require other ways of detecting, launching and communiting with the primary application.
Just detecting a running application has proven difficult (another question hat has not yet been answered), and the Global Atoms approach does not seem to work.
Launching the app if it is not running, is something I have pretty much given up on, given how many different ways the app can be distributed in such a setup, so it will probably have to be a requirement that the application is already running.
Even though I can retrieve what the handle is for the mainwindow, I am not able to use SendMessage either in a Citrix setup. It simply does not process the message I am sending at it. Is that also something XenApp does not support? I could not find find any documentation on this. Alternative ideas to call into the hosted application are very welcome.
In the end the solution(s) was extremely simple for our citrix customers, as they could either:
Open our software first, launch a browser window from within (we have various links that opens browsers), and navigation now works flawlessly.
Customize a hosted browser application, to run in the same server environment as our software, and then our POC was able to launch our software as though it was a regular desktop environment.
I have a kind of odd request- I have lots of users who run my application, and I need to be able to have the app know who is running it. This isn't a problem at all, and I am capturing this info just fine.
The trick is the application needs to access a network share that is restricted- none of the users running the app have permission to do anything there. And there's a lot of stuff going on there- reading files, writing, and since this is a WPF app, data binding to file URI's in that restricted area. To set ImageSource of an Image for example. In all different parts of the application, I need unrestricted access to that data.
I have been looking into the WindowsIdentity.Impersonation stuff, but it seems to be more targeted towards impersonating a user in a small context scope and then ending impersonation.. which is okay, but not convenient.
Is there a way to have my app start and then Impersonate a user within the app scope? So then I could do all the work with the correct permissions sets.
One approach that might work is to set up a Windows service on the users machine that can connect to the server with appropriate Active Directory account privileges. Your application would communicate with that Windows service rather than to the server directly. While this might literally do what you want, the implementation may be more involved than you care to mess with.
Im working on application for Windows Server 2008 R2 (.NET 3.5.1) that would work even after cold reboot, without requring someone to log on any account on the server.
Few words about application itself, it is written in c# application for registering employees work time at the company. Users (employees), have thier cards which are beeing scanned by barcode scanner, each scan means either "work started" or "work stopped", everything is serlialized into xml file which is later on modified and put into .csv but that doesn't matter.
Barcode scanner is working as a keyboard, so all codes are beeing "typed" like from a keyborad, to the PC. I made application read the keys despite the fact that console application is not in focus, or not visible at all.
What i need to do is to make that application work even after cold reboot, it has to be fully automatic.
So far i figured out 2 approaches to do it, one is to create a service which would keep another process alive (if its not working, just turn it on), i didin't have much luck with this one, i have already created service that launches another process for me, but the process is working differently, if i would run it myself, there is no communication with the process so i cannot even tell if its the right one.
Another one is to just put my app into registery /microsoft/windows/current version/run, and enable autologon for user with limited prividges. This actually could work but it is not perfect solution, because after all we do not want to have user logged in on server in company 24/7 right?
I know that most of you are way more experienced in programming than i am, so i would appriciate any solutions how to solve my problem
Lichoniespi
Your options depend on physical security of the system (whether passers-by can do much to it apart from scanning a barcode), but let us assume that it is an easily accessible desktop. In that case, you probably do not want a logged in user.
Use the service approach. You do NOT need a separate process for accessing the keyboard. Create a global hook of type WH_KEYBOARD_LL.
Declare your callback function like this and put it into place with SetWindowsHookEx.
I would use the first approach, create a service, and to comunicate with the running application i would be using a network socket or pipe. For the service be sure that you're using an existing user account (not System) and allow it to interact with the Desktop.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Screenshot of process under Windows Service
I am attempting to more or less emulate Infopath Form Services. So I want to be able to approve or disapprove forms via mobile devices (users will be notified via email). I have the ability to approve/disapprove forms, but the problem is that I need the ability to take screen shots of my program for detailed error reporting (in case something goes wrong during the approval process) (the screen shot process is implemented already). I need the ability to run the program on the server without any user logged in. That is where the problem comes in. If I run my program as a service, I dont get an interactive window, but I get the ability to have my program always run. So I need to be able to launch the program when the computer boots, and have it be able to screenshot itself.
Is there any way to have a windows service have an interactive window at boot, even if its drawn off screen and can never been seen by users, or a way to emulate/fake a window to my program so it can screenshot itself without actually needing an interactive window?
Also, my program is written on the .NET framework in c#
In addition to the fact the service have no desktop to render...
We did not implement rendering of InfoPath forms on the server the way you try because it simply will not work correctly. You can cheat for some time, but running an Office application in headless service mode on a server is simply bad idea. You will also run into interesting issues because user's identity will not match process identity (i.e. can't query ACL'ed data).
You options:
Drop InfoPath portion if you just need approval.
Go with existing solution for mobile forms. There is some support for mobile forms in Forms Services, and you can have very simple views specially for mobile devices if it works. There are also existing solutions for mobile rendering of InfoPath forms.
honestly implement rendering of forms. The XSN format is documented...
Render InfoPath on separate machines with logged on user one per user at a time...
I have been reading a lot about executing a GUI application from a Windows Service. The "Allow service to interact with desktop" check box worked for me when the Service runs as the SYSTEM user (I am using Windows XP).
Now I need the Service to run as a User defined in a domain (from the network). Everything works fine (even if no user is logged into the machine) but the GUIs are not shown (even if the same network user is logged in!).
I know that the GUIs are running, it's just that they are hidden. Why is that? Is there a way to show them if a user is logged on (like when created by the SYSTEM user and allowed interaction with desktop!) ?
if so, would it work if the user logged in is not the same as the one the service is running on?
Edit:
#casperOne: I see your solution, and it is the same that people (even you) have been posting around. In my case though, I am sure I am running on a secure environment and ONLY one user will be logged into a machine at a time. Isn't there anything one can do to simply unhide the GUIs? Why would this work with the user SYSTEM allowing interaction with desktop and not with another user?
Your approach is completely wrong, and will not work when deployed on Vista.
Services should NEVER assume a login session with a desktop to interact with.
Rather, you should have a second application which is run when the user logs in (or some other point in time) which communicates with the service and then displays UI elements when it receives notifications/responses from the service.
See this other question (and answers) for further information:
How to detect if a Window can be Shown?
Short answer: No, you can't do this
Long answer: Noooooo.
Basically, Microsoft are making changes to further prevent this. As casperOne stated, you'll need to separate your UI components away from the service.
And even on XP it didn't work on non domain joined machines (if you have multiple users using Fast User Switching the popups showed up on either the wrong desktop or no desktop at all).
As to why Microsoft changed this, do a quick search for "Shatter Attack" - by isolating service code from the desktop they completely cut off this entire family of security vulnerabilities.