DirectoryInfo.MoveTo - “Source and destination pat

2019-09-21 03:11发布

问题:

I'm trying to figure out what is going on here. I have a routine that looks at all the directories in a directory and removes any non numeric values from the first part of a directory name. For some reason when it goes to do the MoveTo I'm getting the "Source and destination path must have identical roots. Move will not work across volumes." But I'm only providing the new name as the parameter. So the directory might be "007A Raby" and the new name passed into MoveTo would be "007 Raby". Anybody have any thoughts on what I'm doing wrong?

    private void RenameSubs(string directory)
    {
        try
        {
            if (Directory.Exists(directory))
            {
                var parentDI = new DirectoryInfo(directory);

                foreach (var di in parentDI.GetDirectories())
                {
                    var spaceLocation = di.Name.IndexOf(' ');
                    var changed = false;

                    if (spaceLocation > 0)
                    {
                        var oldName = di.Name;
                        var subPartA = di.Name.Substring(0, spaceLocation);
                        var subPartB = di.Name.Substring(spaceLocation, di.Name.Length - spaceLocation);

                        for (int i = subPartA.Length - 1; i > 0; i--)
                        {
                            if (subPartA[i] < '0' || subPartA[i] > '9')
                            {
                                subPartA = subPartA.Substring(0, i);
                                changed = true;
                            }
                            else
                            {
                                break;
                            }
                        }

                        if (changed)
                        {
                            if (!Directory.Exists(Path.Combine(directory, subPartA + subPartB)))
                            {
                                var newName = subPartA + subPartB;
                                di.MoveTo(newName);
                                txtOutput.Text += "Renamed " + oldName + " to " + di.Name + "\r\n";
                            }
                            else
                            {
                                txtOutput.Text += "Error " + oldName + " already exists " + "\r\n";
                            }
                        }
                        else
                        {
                            txtOutput.Text += "Ignored " + di.Name + "\r\n";
                        }
                    }
                }
            }   
        }
        catch (System.Exception excpt)
        {
            txtOutput.Text += "Error " + excpt.Message + "\r\n";
            Console.WriteLine(excpt.Message);
        }
    }

回答1:

Ok, after trial and error I figured out how to fix it. when a "relative path" is passed into DirectoryInfo.MoveTo it doesn't use the Parent Path but the application path. So when I said it worked because it was on the same drive as the application I missed that it renamed the folders to the application folder. To fix this I needed to pass in an absolute path to the MoveTo method. Here is the code change needed inside the "if (changed)" code block to have this work:

    var newName = Path.Combine(directory, subPartA + subPartB);

    if (!Directory.Exists(newName))
    {
        di.MoveTo(newName);
        txtOutput.Text += "Renamed " + oldName + " to " + di.Name + "\r\n";
    }
    else
    {
        txtOutput.Text += "Error " + oldName + " already exists " + "\r\n";
    }

Hope this helps somebody else.