Fog Creek Software
Discussion Board




C# Help

I've done it before and I am doing it again.  I need help....why doesn't this delete the file?

if (strLogFile != String.Empty){        

Console.WriteLine(strLogFile);        
File.Delete(strLogFile);            

}

The file doesn't get  deleted when testing with NUnit.  Am I not understanding how NUnit works?  My thought is that the file should be gone.

Any help?
Thanks.

shiggins
Tuesday, December 09, 2003

I believe you have to close the file before delete will delete it.

Dave B.
Tuesday, December 09, 2003

Actually, Close is not a method in the File class.  Any other thoughts?

shiggins
Tuesday, December 09, 2003

Try using the FileInfo class to delete it.

Dave B.
Tuesday, December 09, 2003

Sorry Dave.  No dice.  And yes the file does exist.  I have tried explicitly setting the path "C:\\MyDocs\\...." and relative paths "log.txt".

shiggins
Tuesday, December 09, 2003

Also, it's not throwing any exceptions.

shiggins
Tuesday, December 09, 2003

Have you tried String.Compare(strLogFile, String.Empty)?

Nick
Tuesday, December 09, 2003

Well, gotta ask the obvious question, have you used a debugger to confirm that the File.Delete line is actually getting called?

What happens if you do

if (true)
{
File.Delete(strLogFile);
}

Does strLogFile have whitespace in it?  Is strLogFile == null (and therefore != String.Empty).

Richard P
Tuesday, December 09, 2003

Nick,

I haven't because I WriteLine the value to the console and the string is correct.

shiggins
Tuesday, December 09, 2003

"Well, gotta ask the obvious question, have you used a debugger to confirm that the File.Delete line is actually getting called?"

How do I use the VS.NET debugger on a class file.  If I set a breakpoint at File.Delete(strLogFile), F5 is grayed out.  That's why I am using NUnit.  As far as I can tell, this line is called.  I have several tests running before and after checking for values, exceptions, etc.  All tests run clean.  So if this line isn't executing, it's the only one in the class that isn't

In VS 6.0 I could set my breakpoint, start the debugger and the run the .dll from an external app and the app processing would stop at my breakpoint so I could see my values.  However, in VS.NET "Start" is grayed out.

No the the following questions:
"Does strLogFile have whitespace in it?  Is strLogFile == null (and therefore != String.Empty). "

shiggins
Tuesday, December 09, 2003

Well, printing merely strLogFile is rather generic.

At least change your print statement to "BEFOREDELETE:" + strLogFile or something.  You may be printing strLogFile elsewhere in your app.

Also, you may be squashing exceptions elsewhere in your app with an overly-broad try/catch.  try doing

try
{
File.Delete(strLogFile);
}
catch
{
Console.Out.WriteLine("Delete failed...");
throw;
}

Richard P
Tuesday, December 09, 2003

And I have no trouble debugging class files.

Check your project properties and make sure you're in debug configuration.  Also, go to the Configuration Manager and make sure the Project that contains the class file is in Debug mode as well.

If even that does not allow you to debug, check your app.config for the appropriate setting.  Something like  <compilation debug="true"/>.

Of course, you have to be using an NT-based OS and be in the Debugger Users group on the machine as well.

Richard P
Tuesday, December 09, 2003

The only thing I can think of is to make sure that you close the file stream used to write to and read from the file before you try and delete it unless you're just trying to delete a file that you haven't been r/w to.  Other than that I can't offer much more advice.

Dave B.
Tuesday, December 09, 2003

//
// YMMV, I didn't compile, or simplify...
//
        if (System.IO.File.Exists(strLogFile)){
       
            System.Console.WriteLine(strLogFile);
            //
            // Clear read-only
            //
            try {
              System.IO.File.SetAttributes(strLogFile, System.IO.FileAttributes.Normal);
            } catch (Exception e0) {
              System.Console.WriteLine("Exception " + e0.Message);
            }

            //
            // Delete File
            //

            try {
              File.Delete(strLogFile);
            } catch (UnauthorizedAccessException e1) {
              System.Console.WriteLine("UnauthorizedAccessException " + e1.Message);
            } catch (ArgumentException e2) {
              System.Console.WriteLine("ArgumentException " + e2.Message);
            } catch (ArgumentNullException e3) {
              System.Console.WriteLine("ArgumentNullException " + e3.Message);
            } catch (PathTooLongException e4) {
              System.Console.WriteLine("PathTooLongException " + e4.Message);
            } catch (DirectoryNotFoundException e5) {
              System.Console.WriteLine("DirectoryNotFoundException " + e5.Message);
            } catch (IOException e6) {
              System.Console.WriteLine("IOException " + e6.Message);
            } catch (NotSupportedException e7) {
              System.Console.WriteLine("NotSupportedException " + e7.Message);
            } catch (Exception e8) {
              System.Console.WriteLine("Exception " + e8.Message);
            }

eclectic_echidna
Tuesday, December 09, 2003

You CAN debug NUnit Tests !!!!!

Just attach the debugger to the nunit-gui.exe when your dll is loaded.

Open the project that contains the unit testing code on visual studio, attach to the process and.. voila!

Jet another C# developer
Tuesday, December 09, 2003

Where's your else?

else
{
    throw new DangerWillRobinsonException("Filed does not exist!");
}

Seriously, you need to put an identifier in your print statements.  It's very possible that you are Console.Out.WriteLine()ing the filename elsewhere and never actually reaching the File.Delete().

Although that seems less likely now.

Richard P
Tuesday, December 09, 2003

Is the content of strLogfile the full path or just the file name, if the latter are you sure what you think is the current directory is the same as the running processes idea of the current directory?

Simon Lucy
Tuesday, December 09, 2003

Well, the docs imply that calling File.Delete on a file that doesn't exist just silently returns.  Tried checking for existence on that path first?

Jason McCullough
Tuesday, December 09, 2003

My spidey senses tell me that this will almost certainly be a "slap yourself damn that was idiotic" sort of incredibly obvious mistake.

Dennis Forbes
Tuesday, December 09, 2003

You're deleting the log file, and then maybe logging some more data?

Big B
Tuesday, December 09, 2003

All of a sudden shiggins goes quiet....I wonder if he:

a) Went to bed
b) Gave up
c) Knocked himself out after figuring out the problem

Ben Richardson
Wednesday, December 10, 2003

Ben,

a) started drinking
b) went to bed

I will try the suggestions above (at least the ones that I haven't tried yet).  I will also post the entire class so you all can see what is going on. It's pretty short.

Thanks.

shiggins
Wednesday, December 10, 2003

namespace mySpace.SystemFramework
{
  using System;
  using System.Threading;
  using System.IO;
  using System.Diagnostics;
  using System.Text;

  public class myLog{

  private string strLogFile;
  private static StreamWriter logWriter;
  private static string;          fulfillNowLogFile= "defaultErrorLog.txt";

  public myLog(){
  Type myType = typeof(myLog);

  try{
    if (!Monitor.TryEnter(myType)){
                
    Monitor.Enter(myType);
    return;}
    try{
      if (myConfiguration.enableLogging){
      strLogFile = myConfiguration.errorFileLocation;                  if (strLogFile != String.Empty){    
                              fulfillNowLogFile = strLogFile;
                              FileInfo objFile = new FileInfo                (fulfillNowLogFile);
logWriter = new StreamWriter(objFile.Open(FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
logWriter.WriteLine("TestMessage");        

try{
File.Delete(fulfillNowLogFile);
}                    
catch  (UnauthorizedAccessException uex)
{
Console.WriteLine(uex.ToString());
}
catch(ArgumentException aex)
{
Console.WriteLine(aex.ToString());
}
catch(ArgumentNullException anex)
{
Console.WriteLine(anex.ToString());
}
catch(PathTooLongException lngex)
{
Console.WriteLine(lngex.ToString());
}
catch(DirectoryNotFoundException dex)        
{
Console.WriteLine(dex.ToString());
}                    
catch(IOException iox)            
{                
Console.WriteLine(iox.ToString());        
}                
catch(NotSupportedException nsex)
{
Console.WriteLine(nsex.ToString());
}                    
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
                    
}
}
}
                
catch(Exception ex)
{
// TODO: Write exception to error log
string strError;
strError = ex.ToString();
}
            
finally
{
Monitor.Exit(myType);
}    
}
}

shiggins
Wednesday, December 10, 2003

Sorry about the formatting above.  The reason I am trying to delete the file was just as a test.  I was having trouble writing to the file so I thought "Let's test deleting and see what happens".

shiggins
Wednesday, December 10, 2003

You have to call logWriter.Close before delete.


Wednesday, December 10, 2003

Tried it...doesn't work.

shiggins
Wednesday, December 10, 2003

And in any case the logWriter isn't deleting the file.  I am calling the static method Delete in the File class to delete the file.

But thanks anyways.

shiggins
Wednesday, December 10, 2003

Ok Spidey...you got me.

After double checking my catches this morining I noticed I was missing IOException.  Added it and got

System.IO.IOException: The process cannot access the file "fulfillNowErrors.txt" because it is being used by another process.


So now my thought is that the process that is blocking is the NUnit process.  Does that mean you can't test any "locking" code using NUnit?  So I will have to write another test class (one that I can fire from a console or window or something) in order to test this? 

Oh, Richard, all my settings are set to Debug but I still can't.

shiggins
Wednesday, December 10, 2003

Try taking out the locking code.  Then close the stream.  Then delete the file.  Any way you look at it, you should close the stream.


Wednesday, December 10, 2003

This works (C# console app):

using System;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Text;

namespace ConsoleApplication1
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            String fulfillNowLogFile;
            StreamWriter logWriter;
            Class1 myClass = new Class1();

            if (Monitor.TryEnter(myClass, 5))
            {    
            
                fulfillNowLogFile = "C:\\Test.txt";
                FileInfo objFile = new FileInfo(fulfillNowLogFile);
                logWriter = new StreamWriter(objFile.Open(FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
                logWriter.WriteLine("TestMessage");       
                logWriter.Close();

                try
                {
                    File.Delete(fulfillNowLogFile);
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.ReadLine();
                }

                Monitor.Exit(myClass);
            }
        }
    }
}


Wednesday, December 10, 2003

It only works if you close the stream though.  Try not closing the stream and you'll get the message you got.


Wednesday, December 10, 2003

Thanks blank!!!!!

That worked.  I had the locking code in to make sure that no two processes are trying to write to the file at one time.  Is there a different way I should have done that?

Thanks again.  I have been struggling with this for some time.

shiggins
Wednesday, December 10, 2003

Well, and I mean this with the utmost respect, if you look at your code above, it is really messed up.

1.  You try and lock an object as non blocking (Moniter.TryEnter).
2. If that succeeds you try and lock the same object again as blocking (Monitor.Enter) inside of a non blocking lock on the same object.
3. You don't close your stream.
4. You have too many exceptions and too many trys.  Use a general exception except for the ones you need to handle.

There may be other stuff, but try cleaning up the code first. (of course I can't stop you from doing things the way want)


Wednesday, December 10, 2003

Thanks for the help.

The reason I used the monitor class that was is because I saw it done in the Duwamish OnLine sample from MSDN.  I am converting my ASP/VB code to C#/ASP.NET and was trying to use Duwamish as a good lesson.  I cut and pasted the Monitor code so it's exactly as Microsoft does it. 

I read up on the Monitor class in the SDK but had some trouble understanding the locks.  See my blog here http://shigginssoft.blogspot.com for my thoughts on this.

I have no problem getting corrected when I'm screwed up.  That's the only way I'll get it right.  I am cleaning my code now.  So do you think Duwamish is maybe not a good sample for structuring my classes, etc.?

Thanks again for your help.

shiggins
Wednesday, December 10, 2003

"it's exactly as Microsoft does it." 

There's your problem ;)

me
Wednesday, December 10, 2003

*  Recent Topics

*  Fog Creek Home