0

I have a "Restore" program written in C # that at one point needs to look for four particular types of files, move any of those types of files to a directory (and first create that directory if it doesn't exist), then move all instances of those types of files into the directory before writing in files from a Backup. Here is my section of code:

private void restoreFromBackup(string chosenFile)
{
    this
    .Cursor = Cursors.WaitCursor;

    // Create new directory in which to move existing .bin and .hid files on the PC

    if (!Directory.Exists("C:\\Phoenix\\OldBinHid"))
    {
        Directory.CreateDirectory("C:\\Phoenix\\OldBinHid");
    }
    else
    {
        Array.ForEach(Directory.GetFiles(@"C:\\Phoenix\\OldBinHid"), File.Delete);
    }

    // Move existing .bin and .hid files to the new directory

    string pattern = @"(\.bin|\.hid|\.BIN|.HID)$";
    var files = Directory.GetFiles(@"C:\Phoenix")
        .Where(x => Regex.IsMatch(x, pattern))
        .Select(x => x).ToList();

    foreach (var item in files)
    {
        Console.WriteLine(item);
        string name = item.Substring(item.LastIndexOf("\\") + 1);
        File.Move(item, Path.Combine(@"C:\Phoenix\OldBinHid", name));
    }

The Create Directory works just fine, but even though I put one example of each of the types of files (Test.bin, Test.BIN, Test.hid and Test.HID) in the C:\Phoenix directory, none of them were moved to the C:\Phoenix\OldBinHid directory. I also then put copies of simlar test files in the C:\Phoenix\OldBinHid directory and ran my Restore a 2nd time - it did not delete any files in that directory either.

What do I have wrong here?

Any help would be greatly appreciated.

Thank you


Hmmm - it is STILL not doing what I want it to do. The Restore will be for when one of our off-site locations receives a new PC that will automatically come loaded with default .bin and .hid files. But our off-site locations will more than likely have built up a number of different .bin and .hid files on their previous PC, which should have backed up the night before by zipping up certain files, to another PC, including all of their .bin and .hid files. What I need to do is have the Restore program check to see if a C:\Phoenix\OldBinHid directory already exists (which technically it shouldn't, but sometimes they have to put the old PC back in place if there are other issues with the new PC) and if it does exist, delete all the files in there. If it doesn't exist, it should create the C:\Phoenix\OldBinHid directory, then search the parent (C:\Phoenix) directory for all .bin and .hid files and move them into the \OldBinHid directory so that when the Restore unzips the Backup, it will put their most current, backed-up .bin and .hid files back in place.

I put several test files (TestA.bin, TestB.BIN, TestC.hid, TestD.HID) in my \Phoenix directory last night, so they would get backed up. I also had a few test files in the OldBinHid directory. I then first tried some of your corrections to what I had in my Restore program, Simon. Did not work - program ran, but nothing was deleted from the \OldBinHid directory and none of my test files were moved there. I then put in a few more test files, so I knew there would be extra test files in my \Phoenix directory and ran my Restore again. Still nothing moved into the Directory and original test files still in the \OldBinHid directory. So I went with your cleaner version - here is what I have:

        // Create new directory in which to move existing .bin and .hid files on the PC

        string sourceDirectory = @"C:\Phoenix";
        string destinationDirectory = @"C:\Phoenix\OldBinHid";
        string pattern = @"(\.bin|\.hid)$";

        Directory.CreateDirectory(destinationDirectory);
        Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);

        // Move existing .bin and .hid files to the new directory

        var files = Directory.GetFiles(sourceDirectory)
            .Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase))
            .Select(x => x)
            .ToArray();

        Array.ForEach(files, file =>
        {
            Console.WriteLine(file);
            File.Move(file, Path.Combine(destinationDirectory, Path.GetFileName(file)));
        });

And still ran without any errors, but nothing got deleted or moved. Am I still missing something here?

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
BigRedEO
  • 807
  • 4
  • 13
  • 33

1 Answers1

2

I've just knocked-up a console app and copied your code in. As @Zong Zheng says, you need to remove the double backslash if you're using string literals. So

@"C:\Phoenix\.."

instead of

@"C:\\Phoenix\\.."

That worked for me. Here is my code (based on yours):

class Program
{
    static void Main(string[] args)
    {
        restoreFromBackup("");
    }

    private static void restoreFromBackup(string chosenFile)
    {
        // Create new directory in which to move existing .bin and .hid files on the PC

        if (!Directory.Exists(@"G:\temp\test2\test3"))
        {
            Directory.CreateDirectory(@"G:\temp\test2\test3");
        }
        else
        {
            Array.ForEach(Directory.GetFiles(@"G:\temp\test2\test3"), File.Delete);
        }

        // Move existing .bin and .hid files to the new directory

        string pattern = @"(\.bin|\.hid|\.BIN|.HID)$";
        var files = Directory.GetFiles(@"G:\temp\test2")
            .Where(x => Regex.IsMatch(x, pattern))
            .Select(x => x).ToList();

        foreach (var item in files)
        {
            Console.WriteLine(item);
            string name = item.Substring(item.LastIndexOf("\\") + 1);
            File.Move(item, Path.Combine(@"G:\temp\test2\test3", name));
        }
    }
}

It exhibits both behaviours - if the directory exists, it deletes anything in there. If it does not exist - it creates it.

Then it copies any files from the base directory in to the subdirectory.

However, if you mix the double backslash and string literal character @, it stops working.

Also, I'd definitely change this line:

string name = item.Substring(item.LastIndexOf("\\") + 1);

to

string name = Path.GetFilename(item);

It's cleaner and more readable and free because it's built-in.

As a further improvement, I'd consider using this overload of the Regex.IsMatch method and specifying 'IgnoreCase' in the RegexOptions param. Then, you can get rid of the .BIN/.bin combinations. This could be a source of your issue (although I've not checked) - what if the file in your folder is Something.Bin rather than Something.bin or Something.BIN? Ignoring the case will eliminate that issue.

Here is a slightly cleaner version of the same code:

    private static void restoreFromBackup(string chosenFile)
    {
        string sourceDirectory = @"G:\temp\test2";
        string destinationDirectory = @"G:\temp\test2\test3";
        string pattern = @"(\.bin|\.hid)$";

        // Create new directory in which to move existing .bin and .hid files on the PC
        Directory.CreateDirectory(destinationDirectory);
        Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);

        var files = Directory.GetFiles(sourceDirectory)
            .Where(x => Regex.IsMatch(x, pattern, RegexOptions.IgnoreCase))
            .Select(x => x)
            .ToArray();

        Array.ForEach(files, file => 
        {
            Console.WriteLine(file);
            File.Move(file, Path.Combine(destinationDirectory, Path.GetFileName(file))); 
        });
    }

Hope this helps you.

EDIT

Given your feedback (still not working), you need to make some mods to the program in order to do some detailed debugging.

1. Firstly, split this line

Array.ForEach(Directory.GetFiles(destinationDirectory), File.Delete);

In to two lines:

var filesToDelete = Directory.GetFiles(destinationDirectory);
Array.ForEach(filesToDelete, File.Delete);

Put a breakpoint after the var filesToDelete... line and add a watch on filesToDelete. What do you see? Are there any file names in the filesToDelete variable?

2. Put a breakpoint on the foreach (var item in files)

And add a watch on the files variable. Again, what do you see?

You need to start breaking it down to see where it fails.

At this stage, my money is now on either (lack of) permissions or incorrect paths/drive letter/wildcards. Are you sure you're looking at the right folders? Drive letters?

Things don't tend to not do anything. They either work or they produce exceptions. It's not often that 'nothing happens'. Unless you are filtering stuff out so that the loops don't actually loop.

Dust down your C# debugging skills and report back...

Also, describe the environment you are running in. Are the files on a local physical drive or across a network? What version of Windows? Is it .NET Windows or MONO? What machine are you running on? Size of files? Diskspace? etc

SimonGoldstone
  • 5,096
  • 3
  • 27
  • 38
  • 1
    THANK YOU ALL! It's been at least 3 years since I've touched C# and I had to jump back in and add pieces to an existing program - this was the one section that was not working for me. I will try various combos here and see what works best for what I need - Thank you again! – BigRedEO Oct 23 '13 at 12:23
  • Welcome. Hope it helps. – SimonGoldstone Oct 23 '13 at 12:53
  • Was out yesterday, but discovered this morning the code DOES work, but in Windows 7 ONLY! Our offsite locations all have Windows XP boxes and I am currently piloting a Windows 7 version of the same PCs to go out to them eventually. This Restore program worked fine on XP for 3 years. It's only this one section that I had to add to it that does not work in XP (and no errors), but does work on my Windows 7 Pilot exactly as expected. I wrote and compiled the code on my own personal work PC (Windows 7), but decided to load Visual C# Express on a test XP box and it said I needed Service Pack 3. – BigRedEO Oct 25 '13 at 14:40
  • So I tried installing Service Pack 3, and that fails (cannot copy a group of files to their destination directory and I haven't found a way around that yet). So I figure until I can put C# on my Windows XP box and run it in Debug there, I may not be able to figure out why it works in Windows 7, but not in XP. The only piece of the code that works on XP is creating the \OldBinHid directory. – BigRedEO Oct 25 '13 at 14:41
  • You could always put trace points in the code and log out to a file, rather than wait to get your app debugging on XP. Trace everything, log all exceptions and you should be able to find the source of the issue. – SimonGoldstone Oct 25 '13 at 15:17
  • Sorry - after ALL that trouble, finally found that the link on my Secure Desktop on the XP system was somehow pointing back to the 3 year old version. *head smack* Put the correct link and all is working! – BigRedEO Oct 25 '13 at 20:49
  • Happens to us all. Glad you got it sorted. – SimonGoldstone Oct 25 '13 at 21:12