Eigentlich gehören kurze Pfade der Vergangenheit an. Doch einige Kommandozeilentools oder auch um die maximale Pfadlänge für Parameter nicht zu überschreiten brauchen die alten DOS Pfade statt der langen Windows Pfade.
Grundsätzlich hilft hier natürlich die Win32 API Funktion:
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint GetShortPathName([MarshalAs(UnmanagedType.LPTStr)]string path, [MarshalAs(UnmanagedType.LPTStr)]StringBuilder shortPath, uint shortPathLength);
Leider kommt es mit der Funktion alleine zu einer Schutzverletzung, wenn z.B. die Datei oder der Pfad noch nicht existiert.
Schlecht ist auch, wenn man der Funktion einen UNC Pfad übergibt oder aber die Zugriffsrechte auf den Pfad eingeschränkt sind.
Aus diesem Grund habe ich mir folgende Funktion gebaut, die dieses Problem nun auf unterschiedliche Arten löst und immer zu einem Ergebniss kommt...
Es muss der Microsoft Scripting Host integriert werden...
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern uint GetShortPathName([MarshalAs(UnmanagedType.LPTStr)]string path, [MarshalAs(UnmanagedType.LPTStr)]StringBuilder shortPath, uint shortPathLength);
private static string GetShortPath(string longPath)
{
try
{
Boolean DeleteBeforeReturn = false;
String MyFile = String.Empty;
String MyDir = String.Empty;
if (File.Exists(longPath) == false)
{
MyFile = Path.GetFileName(longPath);
if (MyFile == String.Empty)
{
MyFile = "loaszu.lop";
}
MyDir = Path.GetDirectoryName(longPath);
DeleteBeforeReturn = true;
File.WriteAllText(Path.Combine(MyDir, MyFile), "", Encoding.UTF8);
}
longPath = System.IO.Path.GetFullPath(Path.Combine(MyDir, MyFile));
const int MAX_PATH = 260;
StringBuilder shortPathBuffer = new StringBuilder(MAX_PATH);
// Violates this rule
GetShortPathName(Path.Combine(MyDir, MyFile), shortPathBuffer, (uint)shortPathBuffer.Capacity);
if (DeleteBeforeReturn == true)
{
try
{
File.Delete(Path.Combine(MyDir, MyFile));
}
catch
{
}
}
return shortPathBuffer.ToString().Replace("loaszu.lop", "");
}
catch
{
Boolean DeleteBeforeReturn = false;
String MyFile = String.Empty;
String MyDir = String.Empty;
if (File.Exists(longPath) == false)
{
MyFile = Path.GetFileName(longPath);
if (MyFile == String.Empty)
{
MyFile = "loaszu.lop";
}
MyDir = Path.GetDirectoryName(longPath);
DeleteBeforeReturn = true;
File.WriteAllText(Path.Combine(MyDir, MyFile), "", Encoding.UTF8);
}
Scripting.FileSystemObject FSO = new Scripting.FileSystemObject();
Scripting.File F = FSO.GetFile(Path.Combine(MyDir,MyFile));
String MyShortDir = F.ShortPath;
if (DeleteBeforeReturn == true)
{
try
{
File.Delete(Path.Combine(MyDir, MyFile));
}
catch
{
}
}
return MyShortDir.ToString().Replace("loaszu.lop", "");
}
}
1 Kommentare zum Snippet