I have a program that start another program. In the second program, I try to delete a File.
If I run directly the second program, no problem, the file get deleted. But if I start the second program from the first program, I get a System.UnauthorizedAccessException.
My guess is that the second program doesn't get all the access of the first program.
I tried many suggestions I found but none of them worked.
Adding Process.StartInfo.Verb = "runas" didnt work.
Adding a manifest file didnt work either (or I did it wrong, not sure)
I set the .exe of the second file to "Run as Administrator" and it didn't work.
Now, how do I fix this?
The first program left the file open, so the second program cannot delete it.
You need to close the file in the first program.
You might be missing a Dispose() call on the FileStream (for example) used to access the file in the first program. That could leave the underlying file in use in that program, although you think the object instances associated with it are gone because they are out of scope.
Post some code if you want better feedback.
Related
EDIT: I'm new to c#, I'm completely lost on this.
I have a program that is supposed to start every time windows starts up. I have it set it up so when you click a check box, it writes / deletes a regedit, code:
private void SetStartUp()
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
if (LaunchCheckBox.Checked)
{
rk.SetValue("SystemStartupProgram", (defaultDirectory + "\\SystemStartupProgram.exe"));
}
else
{
rk.DeleteValue("SystemStartupProgram", false);
}
}
Where "defaultDirectory" is a custom set path. It's set up to be the directory in which the program itself is in, for example "c:\MyProgram\bin\Debug". The .exe file for this program is located in there.
This code works as far as I can tell, since if I go to task manager's start up section, it shows my program, it's location, and it's state, which is enabled. However, the program doesn't run on system start up.
I have a hunch it might be something to do with a .txt file my application uses. The file is located in the same directory. If I remove the .txt file and run my program manually, it tries to launch it but nothing happens. Maybe the windows start up doesn't find the .txt file, and thus can't start it? Is there any way around that?
EDIT 2: The program is a Windows Forms application. When run, it opens up a form. However, it doesn't show up when windows starts.
EDIT 3: Problem fixed, see answer below for details
After a long bug hunt, I found what the reason was. It was indeed what I suspected, when the program starts it tries to look for the .txt file located in the same directory as my .exe. Turns out when you start a program upon system startup, the directory it looks from is something like "Microsoft\windows32", which is not where my file is located at.
I set my program's directory to it's own folder (my case: bin\debug) whenever the program starts, and only then try to read the file.
The bug being fixed, I'm still going to make a windows service application version of it, since that seems to be the correct way to do things from what I managed to google. Thanks to everyone who helped :)
I'm making a little app in C#/.NET that watch for the creation of a file and when it is created it gets its content, parse it and write it in another file.
Everything is working fine so far. But the problem is : there's another process that watch for this file as well. My process is only READING the file while the second one reads it and then DELETES it.
My application is making its job but when it reads the file, the other process can't read it and totally crashes (Not made by me and don't have the sources to fix it).
My application is running very fast and other open the files for a very little time to get the content and put it in a variable so it could close the file faster and then parse the content of the file which is in the variable.
I clearly don't know how but I'd like to be able to read the file and let the other read the file at the same time without any hiccups. Is it possible? I still think that there will be a problem about the fact that the file is being deleted after the other app is done parsing it...
Any suggestions or ideas?
Thanks very much!
You can open the file as follows to ensure you don't lock it from other processes:
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
// do your stuff
}
But if the other process is trying to open it in exclusive mode, it won't help and it will still crash. There's no way to deal with that other than fixing the code for the other process.
KISS: Can you have the file created in a location which the first program isn't looking at, but your software is - and when you are done processing it you then move it to the current location where the first program is looking?
Otherwise:
You are going to have contention since it's going to be a race to see which process actually "notices" the file first and begins working.
I'm assuming you also don't have any control over the process creating the file?
In that case you might look at PsSuspend or PauseSp - if you can control the other process by suspending it until you are ready for it (done with the file) then that might be viable. Not sure how robust this would be.
There's also still the potential race condition of "noticing" the file and performing an action (whatever it is) - keeping the other process paused perpetually until you want it to run (or killing it and starting it) is the only completely deterministic way to achieve what you want within the constraints.
If you are using an NTFS drive (which is very likely), then you can create a hard-link to the file. Essentially, this duplicates the file without actually creating a duplicate. You can read the file with the hard-link. The other process can delete the file, which will only remove their link to the file. This will leave the file in place for you to read. When your program is done reading the file, it can delete the hard-link, and the file system will see that both links have been deleted, and it will delete the file itself.
This can be done from the command line with
fsutil hardlink create <NewFileName> <ExistingFileName>
Or you can P/Invoke the CreateHardLink function in the Windows API.
Can you create another empty zero bytes file called .reading file which has the same name but extension "reading" to it. Then once first process is done reading the file, rename .reading to .done and the second process can check .done files and delete the original file,since both .done and original file have same name but different extensions ?.
#Prashant's response gave me the inspiration for this, and it's very similar, but I believe will solve your problem.
If the other process must match a certain filename pattern
Rename the file to something that
won't match first, a very cheap/fast
operation
Rename it back when finished
If it matches every file in a given folder
Move it to another folder (also a very cheap operation in most filesystems)
Move it back when finished.
If the other process had already locked your file (even for read) then your process would fail, and you can make that graceful. If not you should be safe.
There is still a race condition possibility, of course, but this should be much safer than what you are doing.
I have some code that I wrote to basically clear out the directory every time the program runs through this point. I didn't want to bother enumerating files. If this is a bad way to do this, please tell me.
My main question, however, is about how to deal with the following: one of the files in the folder appears to be in use when it is most certainly not. The program runs on a ButtonClick event, and it exploded the first four or five times, but it worked after I confirmed that nobody was using the file on the server. There is only one person besides myself that would have been using it, and he confirmed that there was nothing running on his side that would be touching the file. Any ideas for what would cause this error/how to avoid it/how to handle it?
I am also having trouble reproducing the error...
string directory = #"\\server\directory\folder\";
DirectoryInfo di = new DirectoryInfo(directory);
if (di.Exists)
di.Delete(true);
Directory.CreateDirectory(directory);
If you are using Windows XP, this may help : http://msdn.microsoft.com/en-us/library/dd997370.aspx#remove_open_handles
Just an extract from the top of this page :
"If you are running Windows XP or earlier, a delete operation on a file or directory that follows an enumeration could fail if there is an open handle that remains on one of the enumerated directories or files."
You may also use a software like Unlocker to identify the process locking your file.
If the file is in use, then someone is most certainly using it. :)
If you can access the server the files reside on, you can use a tool such as Process Explorer to find out which process has opened the file.
Unable to copy file "obj\Debug\FootballLeague.exe" to "bin\Debug\FootballLeague.exe". The process cannot access the file 'bin\Debug\FootballLeague.exe' because it is being used by another process.
I got this problem and I couldnt find any another process.Other c# programmes are working properly.I changed the place which I haved saved first time, but I couldnt get any clue to find the error.
Chances are the other process is FootballLeague.exe - are you sure you aren't still running it?
Another alternative is to use Process Explorer to find out what's got a handle on the file.
If your FootballLeague.exe has been launched and is still running, it is the process that is locking the file.
Do you have a virus scanner turned on? They tend to open files for exclusive access at just the wrong time. I would advise that you turn off real-time scanning in your project directory at a minimum.
Other than that, you'll want to use something like Process Explorer to find out who actually has the file open.
I would post a snippet, but I honestly have no idea what part of my code could possibly be doing this. The program is sizable, I don't want to make you all wade through it. What kinds of things could possibly be the cause of this? Everything works perfectly when called from the command prompt: "readoo.exe". But when I click the exe in its file. . . "readoo.exe has encountered a problem and needs to close. . ."
this is intended to eventually be a scheduled task -> i'm worried, will it work?
i've never debugged, all i've ever used is notepad. I am learning, and feel that this strengthens my understanding of a project.
it crashes nearly immediately. there are no shortcuts, though the file paths are relative.
trying this method: shortcut -> properties -> shortcut -> Start In. I don't have a "shortcut" option
my program reads log files, parses, and creates 4 new files based on the found content
Microsoft Error Report says file not found. But how can this be? the files are there, albeit relative.
Take a copy of your project, and then start hacking bits out of it. When it no longer crashes, you've removed the bit causing the problem.
At what point does it fail when you double-click on it? Immediately, or only when you take a certain action?
You could also add a lot of logging to it, which could indicate where the problem is too.
This is probably looking for a dll that it can't find or is finding a different version from what it wants.
You could try Process Monitor or Process Explorer from sysinternals to see what dlls it loads when it does work and where it finds them.
Try putting a System.Diagnostics.Debugger.Break()call as the first thing in Main() and you'll be asked to attach a debugger - this should definitely show you what is different betweent the 2 invocations.
I would start with identifying what is different in the two methods of execution. Is there a shortcut modifying anything?
The starting directory?
The execution account?
command line arguments?
There are 2 things that it could be:
The current directory could be different when you click on the program or run from the command prompt.
The settings and path could be different when you click on the programe you are using the standard command prompt, are you opening the visual studio command prompt when you run the program from the prompt.
If your application relies on some file that should be on the same path of that exe, that can occurr.
You will have to change the properties of the exe (or shortcut to the exe) to "Start In" the directory where your exe is. For a shortcut, right click on the shortcut -> properties -> shortcut -> Start In.
I guess that is what I think could be the cause.
EDIT: Add a Console.ReadLine towards the end of your code to make it pause for you to see any exception thrown. That should help when you run it using windows explorer.
Put a try/catch around your code and output the exception message to the console in the catch block. That should give you some clues.