How can I force the deletion of locked files in C# - c#

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)

Related

COM Add-in: Resolve the error DisconnectedContext in WinWord.exe

I built an add-on to Microsoft Word. When the user clicks a button, it runs a number of processes that export a list of Microsoft Word documents to Filtered HTML. This works fine.
Where the code falls down is in processing large amounts of files. After the file conversions are done and I call the next function, the app crashes and I get this information from Visual Studio:
Managed Debugging Assistant 'DisconnectedContext' has detected a problem in 'C:\Program Files\Microsoft Office\root\Office16\WINWORD.EXE'.
Additional information: Transition into COM context 0x56255b88 for
this RuntimeCallableWrapper failed with the following error: System
call failed. (Exception from HRESULT: 0x80010100
(RPC_E_SYS_CALL_FAILED)). This is typically because the COM context
0x56255b88 where this RuntimeCallableWrapper was created has been
disconnected or it is busy doing something else. Releasing the
interfaces from the current COM context (COM context 0x56255cb0). This
may cause corruption or data loss. To avoid this problem, please
ensure that all COM contexts/apartments/threads stay alive and are
available for context transition, until the application is completely
done with the RuntimeCallableWrappers that represents COM components
that live inside them.
After some testing, I realized that if I simply remove all the code after the file conversions, there are no problems. To resolve this, I place the remainder of my code in yet another button.
The problem is I don't want to give the user two buttons. After reading various other threads, it sounds like my code has a memory or threading issue. The answers I am reading do not help me truly understand what to do next.
I feel like this is what I want to do:
1- Run conversion.
2- Close thread/cleanup memory issue from conversion.
3- Continue running code.
Unfortunately, I really don't know how to do #2 or if it is even possible. Your help is very much appreciated.
or it is busy doing something else
The managed debugging assistant diagnostic you got is pretty gobbledygooky but that's the part of the message that accurately describes the real problem. You have a firehose problem, the 3rd most common issue associated with threading. The mishap is hard to diagnose because this goes wrong inside the Word plumbing and not your code.
Trying not to commit the same gobbledygook sin myself, what goes wrong is that the interop calls you make into the Office program are queued, waiting for their turn to get executed. The underlying "system call" that the error code hints at is PostMessage(). Wherever there is a queue, there is a risk that the queue gets too large. Happens when the producer (your program) is adding items too the queue far faster than the consumer (the Office program) removes them. The firehose problem. Unless the producer slows down, the queue will grow without bounds and something is going to fail if it is allowed to grow endlessly, at a minimum the process runs out of memory.
It is not allowed to get close to that problem. The underlying queue that PostMessage() uses is protected by the OS. Windows fails the call when the queue already contains 10,000 messages. That's a fatal error that RPC does not know how to recover from, or rather should not try to recover from. Something is amiss and it isn't pretty. It returns an error code to your program to tell you about it. That's RPC_E_SYS_CALL_FAILED. Nothing much better happens in your program, the CLR doesn't know how to recover from it either, nor does your code. So the show is over, the interop call you made got lost and was not executed by Word.
Finding a completely reliable workaround for this awkward problem is not that straight-forward. Beware that this can happen on any interop call, so catching the exception and trying again is pretty drastically unpractical. But do keep in mind that the Q+D fix is very simple. The plain problem is that your program is running too fast, slowing it down with a Thread.Sleep() or Task.Delay() call is quite crude but will always fix the issue. Well, assuming you delay enough.
I think, but don't know for a fact because nobody ever posts repro code, that this issue is also associated with using a console mode app or a worker thread in your program. If it is a console mode app then try applying the [STAThread] attribute to your Main() method. If it is a worker thread then call Thread.SetApartmentState() before starting the thread, but beware it is very important to also create the Application interface on that worker thread. Not otherwise a workaround for an add-in.
If neither of those workarounds is effective or too unpractical then consider that you can automagically slow your program down, and ensure the queue is emptied, by occasionally reading something back from the Office program. Something silly, any property getter call will do. Necessarily you can't get the property value until the Office program catches up. That can still fail, there is also a 60 second time-out on the interop call. But that's something you can fix, you can call CoRegisterMessageFilter() in your program to install a callback that runs when the timeout trips. Very gobbledygooky as well, but the cut-and-paste code is readily available.

GetWindowThreadProcessId Race condition Risk

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.

How to make windows application for single system(machine)

I want to make .exe for desktop application which can only used once in whole life.Nobody can run it twice.
You can not do that reliably.
You may try simple stuff like writing a magic key in the registry or storing a magic file somewhere, but simple tools like Process Monitor will show your magic markers to anyone with Google skills.
You may try to delete the .exe when it is terminating, but if the user makes a copy before they execute your file, you loose again.
You may write a root-kit that prevents the system from launching your application twice, but that is not very nice and it can be detected and circumvented too.
You may create an online service where your application needs check for a one time license to execute, but that can be cracked and you will get a big mess keeping track of one time licenses.
But in the end, if someone really wants to run your application more than once they will figure out how to do it.
How much protection do you want?
Delete itself as it exits?
What you are talking about is a single instance application that can start up, and no other copy can run - the single instance start up code is based on creating a mutex, and if another copy is run, it checks to see if the mutex is allocated, if it is, it bails out and exits immediately. Have a look at this article on CodeProject that does exactly what you're looking for.
It's possible to use a combination of DPAPI calls (ProtectedData Class) to push a value into the registry to check for a second time, or alternatively encode a value on first run and check the result matches the machine you intend it to be run on (and exit if not).
See DataProtectionScope.LocalMachine. The result of the protected data will be almost always different per machine, so this works as a specific-machine check.
You could create a registry key. If the key exists abort execution.

Prevent C# app from process kill

How can I protect my C# app from someone killing its process via taskman or programmatically?
Here is my scenario:
App A is an MFC app developed by another team. It has an unpublished text-based remote interface that is enabled via a backdoor.
I'm developing app B, a C# WinForms app which interacts with A. B enables A's backdoor when it needs remote access closes it when finished (or on failure).
I'm exploring ways users could abuse B in order to gain access to A's hidden functionality, such as killing B's process after it has enabled A's remote interface. I'd like have one last chance for B to close A's backdoor when that happens.
B uses localhost to interact with A, so I'm not worried about the power-down scenario.
I'm looking for a solution that doesn't involve changing A.
I'm not expecting to be able to stop Dark Tangent (though that would be a bonus), but right now a script kiddie could have his way with this design :)
These apps run on Windows XP, but will also soon support Vista & 7.
Thanks in advance,
Jim
I'm willing shut the app down when they try but need to do some things first.
Having necessary steps at program shutdown leads to fragile programs that break easily. Even if you could prevent someone from killing your program via the task manager, you cannot stop them from turning off the computer, or even pulling the cable out of the wall. Whatever task that was so vitally important to complete will be lost. And what if there is a power cut? Again your task won't complete and your vital clean up code will not be run.
Instead you should make your program robust to failures at any point. Use transactions, and always save state to files atomically - make sure that you always have at least one valid copy of your data. Don't overwrite important files in a way that they become temporarily invalid.
Finally, you can add a dialog box to your program that when they try to close it, warns them that the program needs to shut down properly. If you make your shutdown fast users won't want to kill it and will let it terminate properly. If your shutdown takes ages then people will try to kill it. If you are nice to your users, they will be nice to you too.
If shutting down fast means that the user will lose some unfinished work then warn them about this and give them the opportunity to wait for the task to finish, but if they really want to quit your program then let them quit.
You can't - as long as the user has the right to call TerminateProcess on your program, you can't prevent End Process from killing you immediately in task manager. Raymond Chen posted on this some time ago: The arms race between programs and users
You really, really, really don't want to do this. It makes users very angry!! However, if it is supposed to be a service, run it as a service account and don't give admin rights to users.
Short answer: you can't and you shouldn't.
Long answer: You can try to start a second 'helper' process, that checks every x seconds if your app is still running. If it isn't, it restarts it.
If you want a process to run for a long time just don't trust users to keep it running, consider windows services. They are designed for this.
I think everybody has missed the point. If I read it correctly (after your edit) you wish to know when you are being "killed" so you can shut down gracefully?
The point of "killing" is that you "can't" stop it. There are of course workarounds like using a second app to revive a killed app, but that has nothing to do with simply being able to shut down gracefully.
The best approach is to either run as a service (so you can't be killed, just asked to shut down), or to restructure the way your app works so that it doesn't need to "tidy up" before it quits. When an app is quit, most resources it holds are automatically cleaned up, so it's only really your own data that you have to close cleanly. Approaches you could try are:
Frequently commit your state to disk so that you don't lose much (or anything) if you are unexpectedly quit. (Remember to flush all I/O streams to be sure they are committed to disk)
Save information to disk that allows you to detect an unexpected shutdown the next time your program runs, so it is able to detect and rectify whatever problems might have been caused by being killed.
Tell your users not to be idiots, and quit your application nicely. Poke them in the eye if they ignore you. Usually after no more than two times they listen :-)
In order to prevent your application from being terminated, you run your application as another user (i.e. as a service, or as another user account), and limit users to be Standard User.
This way no malicious users can kill your process, since only administrators can kill it, and that is a privilege that you, apparently, don't trust anyone with.
It has the advantage of following the intended design of the operating system.
#Jim
If App A can receive modification requests
Preferably, I would an architecture where all App B's are registered upon opening the backdoor and are required to ping App A with the registration at an interval so that App A can close it's own backdoor upon App B not informing it that it still needs access. This is still not perfectly secure but App A should not be structured with such an interface without some sort of self regulation for "secure" means of communication.
Or, you could suggest App A be modified to check for valid processes and if none are found while it's backdoor is open then it gets closed (this is spoofable since it goes by processed name).
Otherwise, it sounds like App B should shut the backdoor as often as possible when it does not need immediate access.
Requiring an App B to provide security of access to App A is a poor model indeed.
As far as i know you can't, and even if you could you really shouldn't. imagine how annoying it would be if you couldn't force kill an application.
If its important that your application keep running you could always create a windows service that "pings" the application to ensure it is running (you could use named pipes, sockets, pid files... whatever). if the service detects that the process has died then it can just restart it. this is probably your best bet.
When the application initiates for the first time could you not execute a 3rd ap/process that is running in the background and attempts to callback to App B every so ofter, so when that App B is closed.. App C can see that and executes a procedure to close App A's backdoor.
So that when App B closes successfully via the intended Close button it will disable App C from checking App B is still working fine...
Im not really the best with C# at the moment but looking at your problem thats probably one of the ways i would try to do it..
Also if App B checks App C aswell then if App C has gone down App B will close the backdoor if it can.
As the others say this may not be a good idea tho.

Updating an application without closing it

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!

Categories