views:

690

answers:

3

I need to do a check to see if the file exists that they input, How can I do this, I tried using try & catch and it has no effect

if (startarg.Contains("-del") == true)
            {
                //Searches "Uninstallers" folder for uninstaller containing the name that they type after "-del" and runs it
                string uninstalldirectory = Path.Combine(Directory.GetCurrentDirectory(), "Uninstallers");
                DirectoryInfo UninstallDir = new DirectoryInfo(uninstalldirectory);
                string installname = startarg[2].ToString();
                //Removes file extesion "-del "
                installname.Remove(0, 5);
                string FullFilePath = Path.Combine(uninstalldirectory, installname);
                try
                {
                    //Makes the uninstaller invisible to the user and sets other settings
                    Process Uninstaller = new Process();
                    Uninstaller.StartInfo.FileName = FullFilePath;
                    Uninstaller.StartInfo.UseShellExecute = false;
                    Uninstaller.StartInfo.CreateNoWindow = true;
                    Uninstaller.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    Uninstaller.Start();
                }
                //Only is run if the package isn't installed
                catch (System.Exception)
                {
                    Console.WriteLine("The specified package is not installed, you most likely mispelled it or didnt put quotes around it, try again");
                }

            }

Most of that code is getting the current directory and adding "Uninstallers" to it.

Edit: The debug result is a ArgumentOutOfRangeException

I tried using the File.Exists if statement and else and it still crashes

Edit #2:

Just a bit on what I'm to do with this program: I'm trying to write a cross-platform (with mono, haven't ported it yet because I don't like MonoDevelop) package manager, and this is the function of it that deletes the packages. It gets the list of installed applications by getting the uninstall scripts in the Uninstallers folder of the application. I want it to be directory independent so I have it get the current directory

My code works fine if the file exists, but when it doesn't it crashes thats my problem

+3  A: 

It is not good pratice to rely on exceptions for normal processing. You can check if a file exists by using the File.Exists() function and if it doesn't write your alert and allow them to select another file. So it might look like

if(File.Exists(FullFilePath))
{
   //uninstall
}
else
{
   Console.WriteLine("The specified package is not installed, you most likely mispelled it or didnt put quotes around it, try again");
}
stimms
After I changed that, it still crashes
Indebi
@lndebi: crashes where? At what line, and what is the exception?
Michael Petrotta
It crashes at string FullFilePath = Path.Combine(uninstalldirectory, installname);
Indebi
@lndebi: Print out all your intermediate variables, so you can get a little more insight into what's going on. In particular, installName (before and after you modify it) and FullFilePath.
Michael Petrotta
Those variables are fine, I tested each one as I went along, it only crashes when it's got the wrong package name
Indebi
What are the values of those variables?
Michael Petrotta
The Values of those variables are different, because the program will be located in an unknown place, hence why it gets the current directory and adds "Uninstallers" to it.
Indebi
You actually should _not_ check File.Exists() like this. The file system is volatile, and a file is apt to disappear or permissions change in between when you make the check and when you try to handle the file. Until the API provides a "TryOpen()" method, the best thing to do is just handle the exception.
Joel Coehoorn
sound advice, Joel. I'll do that in future.
stimms
+6  A: 

You haven't specified the results that you see, so your problem is hard to diagnose. I can see a few possible problems, though:

  • Path.Combine can throw exceptions if its arguments contain characters invalid in paths. You haven't wrapped your Path.Combine calls in try-catch blocks.
  • If your code requires that a file or directory at a given path exist, you're better off checking that with a File.Exists or Directory.Exists call, rather than depending on an exception. Joel Coehoorn makes a good point in his comment, with respect to race conditions when using File.Exists.
  • Stripping "-del" from your command-line arguments is a fairly error-prone way to handle arguments. Is there any reason you can't simply expect the directive ("-del") to be the first argument, and the path to be the second argument?

EDIT: after reading your replies elsewhere, I see another problem:

 //Removes file extesion "-del "
 installname.Remove(0, 5);

This doesn't do what you think it does. You need to assign the result of that line back to installName:

installname = installname.Remove(0, 5);

I'm also concerned that you're expecting a directive and path to be somehow combined into your third command-line argument. If you invoke your application like so:

myapp.exe foo bar -del "C:\myfile.txt"

Then your command-line arguments will look like the following:

args[0] // foo
args[1] // bar
args[2] // -del
args[3] // C:\myfile.txt

In other words, "-del" and your file path will be in separate arguments.

Michael Petrotta
I'm not trying to get it to execute another program, i'm writing a cross-platform package manager (will port it to mono soon) and this is the part for it to delete packages that are installed. I want the user to be able to type simtho -del "Mozilla Firefox" and it will delete Mozilla Firefox. Don't worry about a lot of the details of it, I have it mostly covered just please help me with this problem
Indebi
Well frankly, lndebi, your code is full of errors, and you'll need to address the details before it'll work in any reasonable way. Is there any reason you're not being forthcoming with answers to the debugging questions I'm asking?
Michael Petrotta
Your 2nd bullet point is wrong, because the file system is _volatile_, meaning a file can be deleted or permissions change in between when you check and when you try to use it. You have to be able to handle the exception anyway, and so so the .Exists() call is just extra.
Joel Coehoorn
@Joel: good point. For entertaining reading, look up the MSDN docs for `File.Exists`, and walk through the changes in guidance from 3.0 to 3.5 to 4.0.
Michael Petrotta
+3  A: 

The try-catch has no effect because the exception is being thrown by code that is outside of the try block. As the other answers point point out, there are several improvements you can make to your code so that your exception handling is invoked for truly exceptional conditions.

Jamie Ide