I am trying to create a batch charsheet creator for my RPG. When the program loads it looks in its file location WORKINGDIR + WAITDIR
for any picture files that have the tags Ready
, Male
and Female
tags and puts them in WORKINGDIR + LIVEDIR
. WORKINGDIR
looks like this:
Debug // WORKINGDIR
├───Live // LIVEDIR
├───Wait // WAITDIR
├───Crew.exe // program
└───Other VS files
When the code is run the error System.IO.IOException: 'Source and destination path must be different.'
is thrown when I try to move the file from one to another. Somehow source
and destination
become equivalent.
const string LIVEDIR = "\\Live";
const string WAITDIR = "\\Wait";
List<string> files = new List<string>(Directory.EnumerateFiles(WORKINGDIR + WAITDIR, "*.jpeg", SearchOption.TopDirectoryOnly));
files.AddRange(Directory.EnumerateFiles(WORKINGDIR + WAITDIR, "*.png", SearchOption.TopDirectoryOnly));
files.AddRange(Directory.EnumerateFiles(WORKINGDIR + WAITDIR, "*.jpg", SearchOption.TopDirectoryOnly));
// ^ adds files that need to be looked through
string[] tags;
ShellFile shellFile;
foreach(string file in files)
{
string source = Path.Combine(WORKINGDIR, WAITDIR, file);
string destination = Path.Combine(WORKINGDIR, LIVEDIR, file);
/*if (source == destination)
throw new Exception();
*/ // This is also thrown
shellFile = ShellFile.FromFilePath(Path.Combine(WORKINGDIR, WAITDIR, file));
tags = shellFile.Properties.System.Photo.TagViewAggregate.Value;
int i = 0;
crewMember.Gender foo = crewMember.Gender.Female;
if (tags == null)
continue;
foreach(string tag in tags)
{
if(tag == "Ready")
{
i++;
}
if(tag == "Female")
{
i++;
foo = crewMember.Gender.Female;
}
else if(tag == "Male")
{
i++;
foo = crewMember.Gender.Male;
}
}
if(i>=2) // if it has two correct tags
{
Console.WriteLine(
$"source: {source}\n" +
$"Destination: {destination}");
// ^ also writes the same paths to console.
Directory.Move(source, destination);
// ^ Error
crewMembers.Add(new crewMember(file, foo));
}
}
What I think is going on is that for whatever reason Path.Combine()
is returning the string that was generated previous instead of a new string. Is there a way around this or am I using it wrong?
The method Directory.EnumerateFiles
gives absolute paths, so each of your file
variables contains an absolute path.
If you supply multiple absolute paths to Path.Combine
, it will output the last one:
Path.Combine("C:\\", "workdir", "C:\\outdir\\test.txt")
yields
C:\outdir\test.txt
(Try it).
This is, because the Path.Combine
method tries to root the output path:
However, if an argument other than the first contains a rooted path, any previous path components are ignored, and the returned string begins with that rooted path component.
Especially for applications which take file names as user input this is a common security pitfall.
Instead either use Path.GetFileName
to get plain file names first, or, if you have access to .NET Core, combine the paths using the new and more secure Path.Join
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With