Reading through the comments of another question, I see that there is risk of encountering race condition(s) when using the GetWindowThreadProcessId Windows API method. How big of a risk is this?
Allow me to provide background into what I am attempting. I am writing a timekeeping app in C# for my own personal use. My intent was to have the app detect (via Win API calls) when the active window has changed so that I can log time against the application being used. I have already located code that detects when the active window changes; now I am trying to determine the process associated with that window. I have located several posts on SO that point to GetWindowThreadProcessId as the solution, but as I mentioned there seems to be a potential issue in using it. If GetWindowThreadProcessId is not a safe way to go, then I am open to other alternatives.
My hope was to keep the code wholly in C#, but I am not (completely) opposed to moving parts of it into C/C++ if necessary.
Thanks!
The race is unavoidable. There's no API that can atomically do what you want.
But it's a rather benign race. What can go wrong? The window is closed just before you ask about it. So you get an error and then try again. All you need to do is be aware of the race condition and check for and handle errors gracefully.
Related
Disclaimer: Yes, I know that the general answer to whether or not to use GC.Collect() is a resounding "NO!". This is the first time in several years of programming that I ever consider using it at all.
Well then, here's the situation: We have developed a C# scripting tool based on the Microsoft.CodeAnalysis.CSharp.Scripting libraries (v3.6.0). It's a Winform GUI with editor etc., not unlike others out there. We use it for the validation of integrated circuits, meaning that its primary task is interfacing lab equipment such as power supplies, pattern generators, meters and the like. For the communication to said instruments we predominantly rely on National Instrument's VISA framework, albeit not exclusively. Some devices are controlled directly via DLLs from their respective manufacturers. In general, this system is working beautifully and by now it is successfully used by quite a lot of design engineers who do not know the first thing about the intricacies of .NET and C#.
At this point I should explain that the user can simply write a method (i.e. on "top-level") and then execute it. The Roslyn-part behind this is that the input is fed to CSharpScript.Create() and then compiled. The execution of a method is done via Script.ContinueWith("method name"). Inside of such a method the user can construct an object like, say, new VISA("connection string"), which connects to the device and then communicate with the device via this object. Nothing forces him or her to care about disposing the object (i.e. closing the connection).
Now, the problem is this: recently, very sporadic crashes of the GUI application have occurred with no feedback at all from the system - the form just closes and that's it. By trial-and-error we are currently 99% sure that if all connection objects are explicitely disposed within a method, the crashes do not occur. So, rewriting the method to something like this fixes the problem:
using(var device = new VISA("connection string"))
{
device.Query("IDN?");
}
The reason why I look into the GC's direction at all is that there is no discernible correlation to any actions from the user. The guys might run such methods for an hour without a problem and then, when scrolling in the editor, when no method is currently being executed, the GUI closes without comment. And that's why I'd like to get some input from people more knowledgeable about Roslyn and the GC:
Are there known issues with this scripting library and GC? (I would very much assume that there aren't)
Since the explicit disposal of objects seem to prevent the issue, might this be one of the extremely scarce situations where the use of GC.Collect() might be warranted? (admittedly, I could not yet test whether that also prevents the problem thanks to of home office)
Any ideas what can cause a .NET application to crash without any kind of feedback and how to obtain more information about such a crash? (the scripting engine is a separate DLL, as are the device drivers; the GUI only handles the graphics)
I am fully aware that this is a rather vague description of the problem with very little source code. This is due to the fact that the application comprises of quite a lot of source code and I have no idea what might be relevant here. Also, all namespaces in the above text refer to Microsoft.CodeAnalysis.CSharp.Scripting, except for VISA, which is self-defined. Obviously, I will gladly answer any follow-up questions for getting to the bottom of this.
Thanks in advance.
Short answer: No. It's not only not warranted, it's completely missing the actual issue.
Further explanation: #canton7 instantly hit the nail on the head when writing
I'd argue that your application shouldn't crash even if a finalizer does end up being called
The root issue hid inside a 3rd party DLL in form of an, at the very least, suboptimal implementation of IDisposable. Once I zoomed in on that, it was rather easy to produce a workaround for that.
My original question is so very misguided that I'd like to state the one that I should have asked:
How do I trace a crash of my C# application when my application's logging does not show anything?
This question has been answered comprehensively in a number of posts. In my case, the crash could be seen in the Windows event log.
I have an application that should send a log when it exits to a cloud function. This means it can take a long time to get an answer if I'm unlucky (sometimes minutes!). I don't want my application to stay in the background for that long so I just want to fire and forget the log message. I don't need 100% guarantees, but as close as possible is of course nice.
What's the best method to achieve this?
I've read the answers to this question, but it's aimed at ASP.Net applications. Is this still applicable for a WPF application that exits and disappears, potentially before there will ever be an answer from the server, or are there better ways in this case?
Thanks!
I have a scenario where I must delete a file. I don't know and don't care who holds the file. I must delete it and they can crush for all I care. (I don't want to kill the locking task)
the only solution that comes to my mind is to use http://www.emptyloop.com/unlocker/ command line interface.
MoveFileEx is not and option as I cannot restart the machine.
is there any more C#ish method/library for this?
im not thrilled using console application API
in case it is not clear.I know the risk involved and I don't need a lecture of why this is a bad practice. if you know how to do what I asked. thank you very much!
if you want to lecture why this is bad - just don't find someone else to bother##
I can't give you a solution but can point you into a direction.
Window's Process Explorer has a function that can make you search for handles:
When you then select that handle you go to the process owning that handle and you can right click on it and Close the handle and also relieve the lock that process has on that file.
So basically you need to find out which API calls Process explorer is using and execute them yourself in your application.
I think what you are asking for is impossible due to the nature of a lock.
How would you feel if another program could just snatch your files and wipe them as you were reading data?
I believe these unlockers detect the process and try to force it to release it's lock 1 way or another(maybe even shutting their process down).
While this may work for most applications some will be more aggressive (think virus scanners for example).
So maybe you need to ask yourself if you want to increase your chances of getting a lock or if you need to be absolutely sure to get a lock.
Edit:
Assuming you can terminate the locker process and you really want to clear those files(no matter the consequences) you could find the process that holds the lock and shut it down.
In this thread they give a few solutions for tracking which process holds a lock(in c# code) via either handle, win32 dll's or even plan .NET code.
Disclaimer Be aware that shutting down a process like this will have a terrible impact on the consistency of that program and you might even do more bad then good(suppose it's writing it's status the the database for example and halfway it gets terminated)
Is it possible to update an application to a new version without closing it?
Or is there a good way to do that without user noticing it was closed?
Typically applications notice on startup that an update is available, then ask the user whether it's okay to update. They then start the update process and exit. The update process replaces the files, then launches the new version.
In some cases you may be able to get away with updating some pieces of an application without a restart - but the added complexity is significant, and frankly it's better not to try in 99% of cases, IMO.
Of course, you haven't said what kind of app you're writing - if you could give more information, that would help.
The application needs to be closed before updating it, because updating an application generally means replacing the executable files (.exe, .dlls, etc.) with their newer versions, and this can't be done without closing the application.
As Jon said, in some cases, you can upgrade the application without closing it. But, this is not advisable, as it might cause failure in the updater, and the whole update might rollback.
Updater can be another executable which will first close the main application, then download the updates, apply them, start the main application, and exit (An example of this is Skype, FireFox, etc.)
You could separate the backend into a separate process/module and update the the backend by restarting it without the user realizing it.
Updating the front end will be a bit trickier, but could be avoided or delayed, if necessary.
A nice and clean way to achieve this would be using dynamic plugins.
You can code your application heavily plugin-based. When an update is needed, unload the plugin that needs to be updated, update the .dll file and load it back into the application.
However, making this invisible to the user may be a tough job, therefore it depends heavily on your design and coding.
I remember InTime having the ability to swap exe's live, however that had to be carefully coded. I know it's possible but as Jon Skeet said, you're likely better off not trying.
Unless you're doing some kind of automation or something very serious... even then, you should consider a failover so you can shut one down / restart if needed.
If you has some some sort of skeletal framework which launched your application and dlls, you could look at CreateDomain. It will take serious design efforts on your part though. Good luck!
is there a way to be notified when a program is executed or terminated by a user in c#? I am talking about all the programs that a user can execute, not just a certain program. I would like to be notified whenever a user execute .exe files.
I can't even think of a keyword to google.
any suggestions would be appreciated!
The closest thing I know of would be to use Hooks.
You can use WH_SHELL Hooks to receive notification any time a new, non-owned, top level window is created or destroyed by the system. This isn't the same as a process, but it's pretty close in many cases, and potentially more useful in others (since it'd show a new word document window opening after one was already opened, even though they're using a shared process).
You might be able to combine that with EnumProcess to check to see if the process list has changed. This would work for tracking windows applications (but not services or console-based applications running in an existing console).
In Microsoft .NET Framework 3.5, you can get a list of Processes and register for the Process.Exited event. I suppose someone could implement a polling system in which they continually looked for new Processes, but that doesn't really notify you when something launches.
-- EDIT --
You might find this article useful. If you're willing to write a kernel mode driver, you can control every process start and finish.
Now, if you really want to get wild, you can hook into Microsoft Detours. Here is an interesting article about that.