| 

.NET C# Java Javascript Exception

1
Ich hab zur Zeit folgendes Problem: Ich kopiere eine EXE von einem Ort in einen anderen. Und das mache ich, weil ich die EXE für einen NUnit-Test brauche. Und später im Test prüfe ich, ob die Datei auch dort existiert, wohin ich sie kopiert habe. Jedoch schlägt mein Test immer fehl. Und ich hab mittlerweile herausgefunden, woran das liegt und das möchte ich hier an einem Beispiel zeigen:

Die Datei nenne ich jetzt beispielsweise CodeKicker123.exe
Diese kopiere ich mit dem Befehl File.Copy von einem Ort zum anderen.
Im Ort 2 heißt die Datei aber nicht mehr CodeKicker123.exe, sondern CODEK~1.EXE. Natürlich schlägt dann mein Test fehl, da er ja auf die Datei CodeKicker123.exe prüft und nicht CODEK~1.EXE.

Was kann ich tun, damit der Dateiname vollständig vorhanden bleibt?

Edit: Was ich noch erwähnen wollte: Bei meinem Test gehe ich sicher, dass die Datei, bevor ich sie kopiere, nicht schon im Ordner liegt, d.h. der Ordner in den ich kopiere, ist vor dem Test geleert worden.
02.04.2012
starki 603 1 8
starki 603 1 8
6 Antworten
4
Der Name wird nicht verändert, es wird der eigentliche Dateiname hervorgeholt.

Jede Datei in Windows hat bis heute als Dateinamen einen Namen, der der 8.3-Konvention genügt, 1 bis 8 Zeichen, ".", Endung 0 bis 3 Zeichen, Zeichen aus dem ASCII7-Vorrat. Windows hat eben als MS-DOS-GUI-angefangen ;-) Erst mit einer FAT-Erweiterung (FAT32?) sind die Long File Names (LFN) dazu gekommen, und NTFS unterstützt sie natürlich. Wenn ich sage: "dazu" gekommen, dann meine ich das so. Windows führt bei jeder Datei, dessen LFN Leerzeichen, mehrere Punkte und / oder Nicht-ASCII7-Zeichen enthält, eine 8.3-Variante mit. Wer sich mit

dir /x

auf einer Befehlszeile / Konsole ein erweitertes dir ausgeben lässt, kann das studieren.

LFN und 8.3-Name können beliebig gegeneinander ausgetauscht werden. Das System arbeitet mit beidem. In Situationen, in denen ich in Batches keine Leerzeichen und " gebrauchen kann, mache ich mir das zunutze. Folgende Batch hilft:

:: lfn2dos.bat
:: ===========

:: Example -> stdout
:: -----------------
:: lfn2dos -> (nothing)
:: lfn2dos "C:\Documents and Settings\All Users\Application Data\Microsoft\Media Player\UserMigratedStore_59R.bin" -> (olddos path)
:: lfn2dos . -> (olddos path of current directory)

:: Redirection
:: -----------
:: Redirection of output is of course possible, e.g.: lfn2dos . > c:\text\olddospath.txt

@for %%I in (%1) do @echo vollstaendig %%~sI
@for %%I in (%1) do @echo original %%~fI
@for %%I in (%1) do @echo Pfad %%~dI%%~psI
@for %%I in (%1) do @echo Dateiname %%~nsI

:: @for %%I in (%1) do @echo %%~dI%%~psI


Wenn ich mit Pfaden und Dateinamen über Stringvergleiche operieren will, muss ich wissen, welche Programmfunktion mit LFN, welche mit 8.3-Namen arbeitet, welche mit beiden, und wie ich das ggf. steuern kann. Oder ich verzichte für das Prüfen auf die Existenz einer Datei auf Stringvergleiche und nehme das Äquivalent für Dir() aus Basic (http://msdn.microsoft.com/en-us/library/dk008ty4%28v=VS.71%29.aspx). Wofür du dich entscheidest und welche Funktion wie arbeitet, muss dir die Referenz verraten.

Oder du bleibst beim Stringvergleich und stellst mit einer Konvertierfunktion aus dem .NET-Vorrat für beide Seiten 8.3 sicher.

Weiterlesen: https://de.wikipedia.org/wiki/File_Allocation_Table
03.04.2012
mupan 575 1 8
mupan 575 1 8
2
Nicht getestet, aber das koennte helfen:
How to Disable Automatic Short File Name Generation
03.04.2012
Martin Fuchs 1,4k 9
1
Wenn ich folgendes Programm unter Windows 7 (64bit) (NTFS) ausführe, funktioniert es fehlerfrei (Ausgabe "ok):

static void Main(string[] args)
{
string copyFrom = "CodeKicker.exe";
string copyTo = "CodeKicker123.exe";

System.IO.File.Copy(copyFrom, copyTo);

if (System.IO.File.Exists(copyTo))
{
Console.WriteLine("ok");
}
else
{
Console.WriteLine("Fehler");
}
Console.ReadLine();

}


Meine CodeKicker.exe wird nach CodeKicker123.exe kopiert. Welches Betriebssystem setzt Du ein, welches Filesystem hat der Datenträger?
02.04.2012
Xantiva 2,3k 2 9
Xantiva 2,3k 2 9
1
Hmmm, bei mir geht's:
System.IO.File.Copy(@"D:\Temp\CodeKicker123.exe", @"D:\Temp\Testverzeichnis\CodeKicker123.exe");

Der Dateiname bleibt bei mir gleich.

Wenn du die Überschreibung der Methode mit dem boolschen Flag overwrite verwendest, musst du das Verzeichnis gar nicht leeren.
System.IO.File.Copy(@"D:\Temp\CodeKicker123.exe", @"D:\Temp\Testverzeichnis\CodeKicker123.exe", true);

Was passiert denn, wenn du die Datei von Hand in das Verzeichnis kopierst? Wird der Name dann auch verändert?
02.04.2012
KN 1,7k 1 8
0
Komisch. Kann es an der Funktion Path.Combine liegen?

Ich zeige hier mal meine Kopierfunktion:
private static void CopyDll(string file)
{
//Prüfen, ob der Zielordner existiert, falls nicht,
//wird ein Ordner erstellt.
if (!(Directory.Exists(CopiedDlls)))
{
Directory.CreateDirectory(CopiedDlls);
}

string sourceFile = Path.Combine(DllsToCopyPath, file);
string destFile = Path.Combine(CopiedDlls, file);

//Kopieren der Datei
//Überschreiben der Datei, falls sie schon existiert
File.Copy(sourceFile, destFile, true);
}


CopiedDlls, DllsToCopy sind zwei String-Konstanten. In dem Ordner DllsToCopy liegen die Dateien, die in den Ordner CopiedDlls kopiert werden sollen.
02.04.2012
starki 603 1 8
1
Wenn es an der Methode Path.Combine liegen sollte, dann schau die doch mal die strings sourceFile und destFile an, wenn du sie erzeugt hast.
KN 02.04.2012
Poste mal bitte die Werte der Konstanten DllsToCopyPath sowie CopiedDlls. Sicherlich vermurkst Path.Combine da irgendwas, da Path.Combine sehr strikt vorgeht.
mkernbach 02.04.2012
0
Also Jungs, danke für eure Hilfe, ich habe herausgefunden, dass das Problem an einer ganz anderen Stelle auftritt. Und zwar, wenn man eine EXE-Datei registriert (oder zumindest die, die ich hier benutze), dann werden zwei Einträge in die Registry geschrieben, einer davon hat die 8.3-Konvention, der andere die normale, so wie ich sie dann im Explorer sehe.

Beim Durchforsten der Registry wird aber die 8.3-Konvention zuerst entdeckt und daher hat der Dateiname dann die 8.3-Konvention und die nicht LFN. Wie ich dieses Problem für mein Projekt löse, muss ich erstmal selbst herausfinden.

Edit: Die Werte in den verschiedenen Variablen war schon korrekt und das Programm läuft auch soweit korrekt, nur der Wert in der Registry war halt nicht so wie ich ihn haben wollte, aber daran kann ich erstmal auch nichts ändern, da dieser von Microsoft automatisch so geschrieben wird.
04.04.2012
starki 603 1 8
starki 603 1 8
Hast du dir den Link meiner Antwort angesehen?
Martin Fuchs 05.04.2012
Also falls den Link zu Microsoft meinst: So leicht geht das ja nicht, da ich ja das Programm auch auf anderen Rechnern einsetzen will ...
starki 05.04.2012

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH