using System;
using System.IO;
namespace MergeHub.Services
{
///
/// 경로를 "윈도우 셸이 받아들이는 모양"으로 맞춰 주는 곳.
///
/// 왜 필요한가 - .NET 의 는 C:/a/b 처럼 슬래시를 섞어 써도
/// 통과시킨다. 그런데 파일 대화상자의 InitialDirectory 는 셸(COM)이 그대로 해석하고,
/// 슬래시가 섞인 경로를 받으면 을 던진다.
/// 그 예외는 ShowDialog() 안쪽에서 올라오기 때문에 대입할 때 감싸 봐야 소용이 없고,
/// 잡지 않으면 프로그램이 그대로 죽는다(실제로 "왼쪽 폴더..." 를 누르면 죽던 원인이 이것이다).
///
/// 그래서 셸에 넘기는 경로는 반드시 여기를 거친다. 확인할 수 없는 경로는 빈 문자열이 되고,
/// 부르는 쪽은 그때 InitialDirectory 를 아예 지정하지 않으면 된다.
///
public static class PathUtil
{
/// 폴더 경로를 정규화한다. 실제로 있는 폴더가 아니면 빈 문자열.
public static string FullFolderPath(string? path)
{
var full = Normalize(path);
if (full.Length == 0) return string.Empty;
try
{
return Directory.Exists(full) ? full : string.Empty;
}
catch (IOException)
{
return string.Empty;
}
catch (UnauthorizedAccessException)
{
return string.Empty;
}
}
/// 파일 경로가 든 폴더를 정규화해서 돌려준다. 확인할 수 없으면 빈 문자열.
public static string FolderOfFile(string? filePath)
{
var full = Normalize(filePath);
if (full.Length == 0) return string.Empty;
try
{
return FullFolderPath(Path.GetDirectoryName(full));
}
catch (ArgumentException)
{
return string.Empty;
}
}
///
/// 구분자를 역슬래시로 맞추고 상대 경로를 절대 경로로 편다.
/// 경로로 쓸 수 없는 글자가 들어 있으면 빈 문자열.
///
private static string Normalize(string? path)
{
if (string.IsNullOrWhiteSpace(path)) return string.Empty;
try
{
return Path.GetFullPath(path!.Trim());
}
catch (ArgumentException)
{
return string.Empty;
}
catch (NotSupportedException)
{
return string.Empty;
}
catch (PathTooLongException)
{
return string.Empty;
}
catch (IOException)
{
return string.Empty;
}
}
}
}