sskodje / ScreenRecorderLib

A .NET library for screen recording in Windows, using native Microsoft Media Foundation for realtime encoding to h264 video or PNG images.
MIT License
409 stars 93 forks source link

Running the Library as Windows Service #197

Closed ademircarvalhojr closed 2 years ago

ademircarvalhojr commented 2 years ago

Hello,

First I want to congratulate you for this amazing project. It makes much easier recording screens at C# projects.

I want to user your library in my project, but I have the requirement to run the recording as a windows service (to simplify, my project aims to record/log a RPA - robotic process automation execution).

The library works like a charm in a console application, but using it in a windows service, it give us some errors and "crash" the service:

"The process was terminated due to an internal error in the .NET Runtime at IP 6F9917FF (6F7E0000) with exit code c0000005"

I googled and read some articles and links at stack overflow. Some of them states things about the "session isolation feature" / "session 0" that is a special session that service runs, and anothers states that maybe services don´t have enough permissions to access these low level DirectX/DXGI windows APIs/methods, even checking the option to "Allow service to interact with desktop" at the service.

I already checked your project history and seen some issues related to running the library as a service, but I´ve not noticed any fix or correction about it in these issues.

Could you check this point again? To help, I built a simple project to record a little video (5s) at every 10s at temporary folder. And as I using Topshelf, it is simple to run it as a console application or installing as a windows service.

If you really going to check, the project is located at https://github.com/ademircarvalhojr/screenRecLib-asServiceExample, and to run as console its is enough clone, compile and run the project. To run as a service, you could run the executable passing the argument "install", and start it at the windows services (the name is Screen Recorder Library Service). And to uninstall the service (and clean the mess), run the same executable with the "uninstall" argument.

The actual (and unwanted) behavior is the service, imediattely after start, crash and stops. The logs can be viewed at windows event viewer.

Congratulations again, and thanks in advance by any help.

Let me know any additional doubt or issue.

Best regards,

sskodje commented 2 years ago

Microsoft has for security reasons made limitations on what services can do, and one of them is that they can not access the desktop or graphics pipeline. You used to be able to "Allow service to interact with desktop", but this is no longer possible. You need to launch some sort of application from Windows to be a ble to access it.

jessp01 commented 1 month ago

Hello @sskodje , @ademircarvalhojr ,

I realise this is an old issue and am aware of the Session 0 Isolation MS introduced starting from Windows 7 but I was wondering whether anyone has come up with a workaround or a solution that would enable accessing the graphics pipeline (aka "interact with desktop") from a service.

To give some context: the code that captures the screen display and camera output needs to run in the background (as a service/scheduled task, etc), regardless of active user sessions. In other words, it must work even when no user is logged in and continue to record through sign out/switch user events.

I have looked at https://learn.microsoft.com/en-gb/windows/win32/services/interactive-services And made sure to set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\NoInteractiveServices to 0 but, as expected, that did not help.

The doc above also reads:

If this service runs on a multiuser system, add the application to the following key so that it is run in each session: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

And so, I have created a string value with the path to the service's exe (basically the code @ademircarvalhojr shared, with a few changes). That works to an extent: when I reboot the machine, it starts recording and when I log in as a user, cmd.exe automatically opens with the log and I can see that the recording started before I logged in (which is good). However, if I then logout, the process is terminated so, does not quite get me to where I need to be.

Another acceptable solution could have been automatically logging into a designated local user, starting the capturing process and then locking the screen (so that, from a user perspective, the whole process is rather seamless) but, of course, as soon as I switch users, OnRecordingFailed is triggered with: The object was not found. If calling IDXGIFactory::EnumAdapters, there is no adapter with the specified ordinal

If I try to then start a new recorder (from the same process), I get Object reference not set to an instance of an object in ScreenRecorderLib.DisplayRecordingSource.getMainMonitor()

I was told that Echo360 is capable of running this way on Windows 10 and while I do not have access to that software, https://support.echo360.com/hc/en-us/articles/360035404751-EchoVideo-Device-Monitor-Overview-Administrators does state:

The EchoVideo Device Service is a service-level version of the Device Monitor software that does not require a user to be logged into the podium PC

I'd appreciate any pointers for accomplishing this. Any solution that would allow the recording to run on Windows 10 and 11 regardless of active user sessions could work. In case this is of interest, the use case is a lecture hall where lecturers may or may not log in at any point of their lecture. Obviously, if they want their screen display to be recorded, they'll log in but sometimes, they only want the cam and audio to be captured and therefore, do not log in at all.

Thanks in advance,

PS Excellent work on this project, very useful and well documented.

sskodje commented 1 month ago

I pushed a fix for the exception when calling getMainMonitor with no display output available. The other issue i believe can be a timeout issue, unless it happens immediately. This is the code handling the error. It should say in the logs, if you enable logging to a file.

jessp01 commented 1 month ago

Thanks @sskodje. I see you've pushed several other fixes. I imagine you'll be release a new package soon? I look forward to testing and would rather use an official Nuget package rather than build locally.

Thanks again,

sskodje commented 1 month ago

Soonish. I have some other stuff i want to add as well. You can also download automatic builds here, if you want to test without building yourself.

jessp01 commented 1 month ago

Hi @sskodje ,

Once again, thank you for your work on the issue and this project in general. I realise that what I'm about to ask is somewhat off topic but as you clearly have expertise where it comes to Microsoft Media Foundation (and probably DirectShow as well), I was hoping to get your advice.

I should note that I code on Unix (mostly Linux) exclusively and therefore may be missing something obvious.

What I'm basically looking for is a way to record the camera output continuously across logout and switch user events. If I autologon a user at startup and start a console application which uses your library and then lock the screen, the recording continues but as soon as I log in a different user, the camera is shut down. Is there any way to keep the camera running and continue recording the output regardless of the active user session?
Ideally, I'd rather avoid a filter driver (for obvious reasons) but if you have good examples for that, I'd be happy to look into them as well.

In my searches, I've found https://github.com/flowerinthenight/windows-camera-class-filter-driver and https://www.virusbulletin.com/virusbulletin/2018/09/through-looking-glass-webcam-interception-and-protection-kernel-mode/ which references some repos but as I wrote, I'd rather not venture into kernel space at all for this.

Many thanks in advance for any pointers you may provide,

sskodje commented 1 month ago

Hi, sorry for slow replies. I don't have much knowledge about this problem, so unfortunately i can't be much help. Recording camera, audio, dekstop or similar across logged in users sounds like something Microsoft do not want you to do without very good reason.