Preventing Windows Error Dialog for Console App - c#

I have a .NET service that monitors a windows share location for console apps written in Fortran, launches them, monitors STDOUT and STDERR, and copies output back to a shared location where it's processed by other services. A few instances wrote output that they were terminating, then the app appeared to lock up (it never terminated). I ran the app that failed with the same input on my local machine, and discovered that there was a memory corruption error caused by, I'm assuming, an attempt to deallocate the same memory twice. A windows error dialog was displayed. I determined that, even though my service was running these console apps as windowless apps, when the error occurred in the Fortran console app it continued "running" because there was no user available to click on the dialog.
Using System.Diagnostics.Process, is there any way to prevent the Windows error dialog? Is there a way to prevent it without making global registry changes? I don't want to turn off this behavior globally.
All I could find by googling this issue, is that the user either 1) Should write appropriate error handling (something that can't be done in Fortran code I don't own), or make changes to the registry (something that I consider wrong because I don't control how other users are using the server).

Related

Xamarin.Mac application hang when interacting with filesystem for end-users

I'm working on an internal company desktop app that gets distributed via an internal intranet site. The app is written in C# using Xamarin.Mac and Visual Studio for Mac and works fine locally until I compress the *.app file and upload it to the intranet site to be downloaded by end users.
When a user (including myself), downloads and launches the application it completely locks up trying to perform any actions where it interacts with the users local filesystem (No errors or warnings are displayed/no crashes are seen, it just stops executing any more code. The UI continues to update but nothing else happens).
The weird part is that if you right-click the '*.app' file, select "Show Package Contents" then browse into 'Content' > 'MacOS' and double-click the copy of app contained in there, everything works fine and without any problems.
I'm not an expert on OSX so I'm really struggling to understand what could be causing this behaviour and also what the difference is between launching a Xamarin.Forms app via the '*.app' file and the executable located inside this at 'ProgramName.app/Content/MacOS/ProgramName'.
I've checked/confirmed the app isn't being sandboxed and it's being signed/notarized using the correct distribution certificates/provisioning profiles as far as I can tell, so as far as I'm aware there shouldn't be any security restrictions preventing the required filesystem access. Unless there's something I'm missing.
Is there any way I can get more insight into what is causing this behaviour, such as any debugging tools I can use to understand/view any potential problems with the app itself/the way it's being built?
Thanks!
Managed to finally get to the bottom of this one: The issue was because of a security system Apple have in-place known as 'App Translocation'.
There's a description of this here for anyone who isn't familiar: https://lapcatsoftware.com/articles/app-translocation.html - The tl;dr is that downloaded applications are marked as 'Quarantined' and when ran they're copied to a virtual read-only file system and executed from there. This prevents the application from having any access to the local filesystem (Regardless of if the application is signed/notarized or downloaded from a 'trusted' source etc).
There are two ways to 'unquarantine' an application:
Manually move the application to a different location via Finder (e.g. Drag/drop it into '/Applications' or '~/Documents' (Note: Moving the folder the app is located in/was extracted too isn't enough - You have to physically move the *.app file itself). Apple treats this action as the user considering the application as safe and removes the quarantine flag during the move operation (This has to be done via Finder, it cannot be done via command line operations such as mv).
Run the following command from Terminal to remove the quarantine flag:
xattr -dr com.apple.quarantine '/path/to/downloaded/program.app'
You can detect if you're application is being affected by App Translocation in a number of ways, for instance:
Using 'Console' you can see the path of your executable is something like '/private/var/.../AppTranslocation/....' (This is something I spotted in the Console when previously debugging, but I didn't know enough about OSX to understand exactly what I was seeing and initial attempts to understand this didn't yield any useful information at first)
Run the command xattr /path/to/downloaded/program.app. If the following is seen in then output:
com.apple.quarantine
Then it means the application will be affected by App Translocation.

How can I get the MainWindowHandle of a Windows 7 application running as user <foo> from within a service running as Local System?

I've created a service that runs as the Local System user. This service launches and monitors a Silverlight Out-of-browser application using native interop and the CreateProcessAsUser() method (to run it as the currently logged-in user, rather than Local System). I'm able to get a handle on the spawned Process and do things like Kill() it, however, I've become aware that the service is unable to get a handle to the main window of the child application because the child application is running as a different user. I'm running on Windows 7.
My end goal is to respond properly to when the Process stops responding (i.e. Process.Responding == false) so that I can kill the application and restart it. However, Process.Responding requires a handle to the main window of the process (Process.MainWindowHandle, to be exact), however, in this scenario, Process.MainWindowHandle always returns 0.
I'm stumped here. Is there any way for one user to get a window handle to a process running as another user in Win 7?
Thanks in advance for any and all help.
No, that's not possible. Windows Services are completely isolated from user-mode applications for security reasons. If you could get the handle to a window, you could manipulate and otherwise interact with that window, leaving open a huge security vulnerability.
More information is available here:
How can a Windows Service start a process when a Timer event is raised?
How can I run an EXE program from a Windows Service using C#?
windows service (allow service to interact with desktop)
Need suggestion on replacing Windows Service by invisible WinForm Application
Strictly speaking, what you're using the Windows Service for in the first place is bad design. It shouldn't be creating or launching any user-mode processes, or interacting with the user in any way. Remember that services run even when there is no user logged in! Thus, they shouldn't be starting applications.
A better solution is a simple background application, set to launch automatically when the user logs in. This background application could then launch the Silverlight application, monitor its state, and interact with it as necessary, because both would be running under the context of the same local user account. The effect is similar to a service, but without any of the drawbacks of isolation. The easiest way to do this in Visual Studio is to create a WinForms application (or possibly a WPF application, I have less experience in that area) that simply doesn't show any forms/windows.

C# application keeps freezing on remote

I am developing a C# application (.Net 3.5, Win Forms) which is run on a server, and is accessed by Users using remote desktop. The application keeps freezing on seemingly random occasions on the remote machine (i.e. all GUI components turn to white, task manager reports the application to be not responding), but not when run locally (I'm not entirely sure about that, but failed to reproduce the freeze on my machine).
Has anyone experienced such behavior in his apps that are accessed remotely? What debugging strategy would you suggest? Do I need to consider something special when developing Win Forms applications that are accessed by remote desktop?
EDIT: some notes about the application and the freeze: The application does not recover from the freeze. Also, the freeze does not happen (or did not happen yet) during user interaction, but in between log ins to the remote machine. The application monitors a CFD solver, so it's doing things even when no one is using it.
UPDATE:
We did infact implement detailed logging, writing every function call to a file with a timestamp. Unfortunately, the results were not very conclusive. I.e. the last function call logged always returned correctly. Also, there were some background timers still running, even though the application appeared frozne (GUI completely white etc.). After some trouble we managed to have a look at a crashdump in WinDBG. On the system thread we found a call to OnUserPreferenceChanged() and further up to Invoke.WaitOne(). We can't say for sure yet, but it seems to be the issue decribed in these articles. As a quick fix, I installed a dummy handler to the event mentioned. I'll report how this works out.
UPDATE 2:
As it turns out, a Log In to a remote machine fires several OnUserPreferenceChanged() events. So it was indeed the suspected issue. The fix turned out to be not so easy though. I would have expected that an IllegalCrossReferenceException is thrown everytime a background thread tries to modify a control that was created on the system thread. This does not seem to be the case. I named my system thread and before each access to a control I asserted that the current thread name is the system thread's name. In various places this assertion failed (e.g. in a callback from a timer), but no exception was thrown. After using proper delegation at these places, the freezes stopped. The application runs nonstop for some weeks now and my users are happy again ;)
I do not think the freeze has anything to do with remote desktop. Adding logging was a good suggestion. I have a few suggestions, but without knowing the details of you application I can't get too specific.
The simplest suggestion I have is to check the memory useage and CPU usage in task manager when the freeze occurs.
If adding detailed logging is not an option, add just enough logging to know WHEN the application freezes. This could simply be a thread in the application which writes a timestamp to a file once a minute. Then you can see if there is any pattern in when it freezes, such as after a user has logged off, or when some of the data which you are monitoring changes, or at a certain time each day, or after being online for a certain amount of time.
A final and very hacky solution is to write a small watch dog application. This application's only job is to periodically check on the main application to make sure it is still responsive. How you dow this various drastically based on what your application does. If the watchdog sees the the main application has stopped, it can kill the thread for the main application and re-start it from the binaries.
if your using application streaming your server could be slowing the connection or waiting for packets that are dropping this can create this if your physical using windows remote desktop then there is your problem intense applications are not supposed to be run though remote desktop
AFAIK, there is no difference. Additionaly, I never experienced such a problem. I suggest, you try the following:
Extend your application with extended logging, to see what the users are doing when your application freezes
Check the network connection that is used to connect to the remote machine
Check the CPU usage during the freeze
If the freeze is for an extended amount of time, try to do the following:
Reproduce the freeze via remote desktop.
Go to the machine you just reproduced the freeze on and log in directly and see, whether the application is still freezed
If it is windows 10 version 1903 plus version. Then probably its the issue of windows. Please try the following settings:
Have read various blogs and concluded that the GPO has to force to use XDDM rather than WDDM. The issue is observed with windows 10 version 1903. Currently tested the workaround on machine NDT-61. It is working fine. Please practice the same for respective environment and let me know if some issue is faced.
Steps to Follow:
Open Group Policy Editor
Explore Administrative Templates
Explore Windows Components
Explore Remote Desktop Service
Click Remote Session Environment
Under Remote Session Environment Disable Use WDDM graphics display drive for Remote Desktop Connections
Note:
This policy setting lets you enable WDDM graphics display driver for Remote Desktop Connections.
If you enable or do not configure this policy setting, Remote Desktop Connections will use WDDM graphics display driver.
If you disable this policy setting, Remote Desktop Connections will NOT use WDDM graphics display driver. In this case, the Remote Desktop Connections will use XDDM graphics display driver.
For this change to take effect, you must restart Windows
Observation:
The policy settings are only available in windows 10 version 1903 and plus [ideally since when the issue started].

Alternative to "Allow service to interact with desktop"?

I have a windows service (C#) installed on a server that launches every 10 minutes an executable file (C#) to process some images from one directory to another. No interaction is required with any user. Nevertheless, since the executable file as an output window, to make the service run I have to enable the "Allow service to interact with desktop" checkbox which is considered as an insecure and bad practice. How would I go about this problem? I like to have the executable separated from my windows service because
it makes it easier to debug and
doesn't require a full windows service redeploy.
sometimes I use the same windows
service to launch several
executable files at different
intervals (but all related to the same
project).
EDIT:
When the interaction with the desktop is not enabled, the console application does not get executed correctly and the following error appears inside the Windows Logs:
Faulting application myapp.exe, version 1.0.0.0, time stamp 0x4b8304c3,
faulting module KERNEL32.dll, version 6.0.6002.18005, time stamp 0x49e03821,
exception code 0xc0000142, fault offset 0x00009eed, process id 0x10ec,
application start time 0x01cab736950a64b5.
Once the desktop interaction is enabled, application gets executed normally.
Any thoughts?
Thanks a lot for your time.
If you are using Vista and later and you don't really need any interaction with the user, but have an interactive exe to execute, the Session 0 isolation feature should help alleviate some of the concerns about the 'bad practice' on having a service interact with the desktop (which in Session 0 has no physical console).
This Session 0 isolation would prevent unprivileged users from performing Shatter Attacks on your service as they get their interactive desktops in different sessions. Shatter attacks are the main reason why this 'interaction with desktop' was considered bad practice and if you are using Vista or later, it should be ok if you cannot avoid it (or will have to spend too much effort to do it).
So, if things are working fine as they are, you are probably ok.
Of course, after an OS update, things might just stop working, so it is probably better to prepare to move the dependency on interactivity out, as you don't really need it.
I know this is a bit late but in this circumstance i would use the task scheduler and not bother with the windows service. The task scheduler has a comprehensive set of scheduling options and can run console applications without issue.
If you can, I would recommend rewriting your executables that handle the move to not use an output window. If they are standard, console applications with no output, you can execute them from within a service without requiring "Allow service to interact with desktop". This provides you all of the benefits, without any changes to your service.
Is the subprocess just a console application? I've not written Windows Services, but I think perhaps just starting the subprocess without a window would be sufficient. Use the overload of Process.Start that takes a ProcessStartInfo and set ProcessStartInfo.CreateNoWindow to true.
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.createnowindow.aspx

Unable to execute a program from a service

I have a Windows service which I want to periodically execute an external program. I'm currently doing this the usual way
Process program = Process.Start(#"C:\mpewatch\db_parameters\DBParameters.exe");
This doesn't seem to be working. I'm executing this from a separate thread which is started in my service's OnStart handler. Is there any conceptual problem with this? Is it not possible to execute external programs from a service like this?
You can execute external programs from a service, but there are security issues. For example, your service may be running under an account which does not have read access to the folder where the external program resides, even if your interactive account does have that access.
For test purposes, try to configure the service to run under your interactive account. If the program is invoked as expected, then the problem with the original account is that it does not have sufficient privileges to run the program.
Your question didn't indicate the operating system.
On Windows XP, you can configure your Windows service to interact with the desktop by opening the service control panel, double-clicking your service, selecting the Log On tab, configuring the service to run as local system, and checking the checkbox. It's pretty straightforward. You might try testing with something like Notepad.exe just to see if you can get it working.
On Vista (and presumably Windows 7), however, you may be out of luck. I have read that the ability for Windows services to interact with the desktop has been removed in Vista. I forget what the terminology is, but basically services will run in "shell 0," whereas users will occupy "shell 1". User applications will be able to communicate with services and vice versa using technology like WCF, but services will not be able to communicate directly with the desktop. For example, any error boxes that pop up will have to be dealt with by swapping to "shell 0." Again, this is based on something I read a few months ago, and I haven't gone looking at it again. For me, I've structured my Windows service to be configured using WCF via a front-end app.
I'm sorry I don't have a link for you, but if your service will eventually have to migrate to a newer OS (or you are already there), this is something to check on.
Another critical consideration with Windows Services is that there is no GUI. Technically, there is an option to allow the service to interact with a local GUI, but you will not see it. This is due to services running as the Local System user.
Within a service, any modal dialog box (OK, Cancel, etc) is considered an error.

Categories

Resources