Entwickler-Ecke
IO, XML und Registry - kopierte datei ist leer
ezra_k - Mi 12.01.11 18:44
Titel: kopierte datei ist leer
Hallo
Im Rahmen eines Projektes, möchte ich gerne von der C#-Applikation eine Datei löschen, eine andere kopieren und in den Namen der gelöschten Datei umbenennen.
Dies habe ich folgendermaßen gemacht:
C#-Quelltext
1: 2:
| File.Delete(@"C:\Users\...\Datei1.csv"); File.Copy(@"C:\Users\...\Datei2.csv", @"C:\Users\...\Datei1.csv"); |
In der Laufzeit wird der Code auch ausgeführt und die Datei gelöscht respektive kopiert. Allerdings ist die kopierte Datei ohne Inhalt.
Wichtig ist wahrscheinlich noch, daß beide Dateien während der Laufzeit von jeweils einer anderen Applikation in Benutzung sind.
Wenn ich aber die gewünschten Aktionen selbst per hand im Datei-Explorere während der Laufzeit vornehme, funktioniert alles einwandfrei und die neue Kopie ist nicht leer.
Kann mir da jemand helfen ?
Vielen Dank
Moderiert von
Christian S.: C#-Tags hinzugefügt
jaenicke - Mi 12.01.11 18:52
Dann versuche es mit der API. SHFileOperation benutzt der Explorer.
ezra_k - Sa 15.01.11 18:18
Vielen Dank für die schnelle Antwort. Kenne mich mit der API-Programmierung und C++ leider nicht so gut aus. Habe nach einiger Recherche folgenden Code erstellt:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42:
| namespace APIFILEOPERATION { class class1 {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct SHFILEOPSTRUCT { public IntPtr hwnd; public uint wFunc; public string pFrom; [MarshalAs(UnmanagedType.LPWStr)] public string pTo; [MarshalAs(UnmanagedType.LPWStr)] public UInt16 fFlags; [MarshalAs(UnmanagedType.I2)] public bool fAnyOperationsAborted; public IntPtr hNameMappings; public string lpszProgressTitle; }
[DllImport("shell32.dll", CharSet = CharSet.Auto)] static extern int SHFileOperation(ref SHFILEOPSTRUCT file0p);
public static void Main() { SHFILEOPSTRUCT file0p = new SHFILEOPSTRUCT(); file0p.wFunc = 0x0002; file0p.pFrom = @"C:\fileop_test\test1.csv0"; file0p.pTo = @"C:\fileop_test\test2.csv0"; file0p.fFlags = 0x100;
int result = SHFileOperation(ref file0p); }
}
} |
Wenn ich diesen ausführen lassen will, kommt die Fehlermeldung:
Zitat: |
Das Feld "fFlags" des Typs "SHFILEOPSTRUCT" kann nicht gemarshallt werden: Ungültige verwaltete/nicht verwaltete Typenkombination (Int16/UInt16 muss mit I2 oder U2 kombiniert werden). |
Deshalb hatte ich schon
Zitat: |
17: [MarshalAs(UnmanagedType.I2)] |
eingefügt, was aber leider nichts gebraucht hat.
Was muß ich hier korrigieren ?
Vielen Dank
Kha - Sa 15.01.11 18:43
Das falsche Attribut hast du aber schon entfernt? Lass einmal alle bei diesem Feld weg, das sollte auch so funktionieren.
jaenicke - Sa 15.01.11 19:20
Ich kenne mich mit API-Einbindung unter C# auch nicht wirklich aus, aber ein kurzer Blick zu Google brachte gleich mehrere fertige Beispielquelltexte zu Tage:
http://www.codeproject.com/KB/shell/csdoesshell2.aspx
Das sieht auch logisch aus, denn die Funktion bekommt als Quelle und Ziel ggf. mehrere durch ein Nullzeichen getrennte Zeichenketten. Das funktioniert vermutlich mit einem normalen C#-String nicht so gut.
Zudem wird hier Int32 als BOOL benutzt, ich vermute das wird dann schon richtig sein.
ezra_k - So 16.01.11 11:54
Zitat: |
Das falsche Attribut hast du aber schon entfernt? Lass einmal alle bei diesem Feld weg, das sollte auch so funktionieren. |
Peinlich, habe die Attribute falschrum angehängt (unter statt über). Nach Korrektur ließ es sich dann kompilieren. Ebenso wenn man sie, wie von dir vorgeschlagen, wegläßt. Allerdings führt das Programm nun nicht aus was es soll (siehe unten)....
Zitat: |
Das sieht auch logisch aus, denn die Funktion bekommt als Quelle und Ziel ggf. mehrere durch ein Nullzeichen getrennte Zeichenketten. Das funktioniert vermutlich mit einem normalen C#-String nicht so gut....Zudem wird hier Int32 als BOOL benutzt |
Verstehe leider nicht genau was du meinst. Könntest du mir vielleicht noch einen Hinweis geben. Durch Studium der Seite ist mir aber aufgefallen, daß es wohl
C#-Quelltext
1: 2:
| file0p.pFrom = @"C:\fileop_test\test1.csv\0\0"; file0p.pTo = @"C:\fileop_test\test2.csv\0\0"; |
heißen muß. (Bisher hatte ich nur eine Null nach csv)
Allerdings scheint bei Ausführung des Codes nicht zu passieren. Insbesondere die angestrebte Fileoperation wird nicht ausgeführt...
Der Code sieht jetzt so aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49:
| using System; using System.Runtime.InteropServices;
namespace APIFILEOPERATION { class class1 {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct SHFILEOPSTRUCT { public IntPtr hwnd; public uint wFunc; public string pFrom; public string pTo; public UInt16 fFlags; public bool fAnyOperationsAborted; public IntPtr hNameMappings; public string lpszProgressTitle; }
[DllImport("shell32.dll", CharSet = CharSet.Auto)] static extern int SHFileOperation(ref SHFILEOPSTRUCT file0p);
public static void Main() { SHFILEOPSTRUCT file0p = new SHFILEOPSTRUCT(); file0p.wFunc = 0x0002; file0p.pFrom = @"C:\fileop_test\test1.csv\0\0"; file0p.pTo = @"C:\fileop_test\test2.csv\0\0"; file0p.fFlags = 0x100;
int result = SHFileOperation(ref file0p); }
}
} |
Was könnte jetzt noch falsch sein ?
Vielen Dank für die bisherige und weitere Hilfe
Delete - So 16.01.11 12:08
Dann werte doch mal den Rückgabewert aus und rufe mal GetLastError, damit du siehst, woran es liegt. So können wir wohl auch nur raten. Genauso könntest du das mal bei File.Copy machen. Denn intern werden beide Funktionen letztendlich die gleiche API-Funktion aufrufen, um die Datei zu kopieren.
Hast du mal nach den Rechten geguckt?
ezra_k - So 16.01.11 17:03
Zitat: |
Dann werte doch mal den Rückgabewert aus |
Da kommt 124 raus...
Zitat: |
und rufe mal GetLastError |
C#-Quelltext
1:
| int lastError = Marshal.GetLastWin32Error(); |
ergibt 0...
Zitat: |
Hast du mal nach den Rechten geguckt? |
Ich denke die sind das Problem wenn ich File.Copy benutze. Die SHFILEOP-Lösung teste ich bislang isoliert, d.h. die zu kopierenden Files werden von keiner anderen Applikation benutzt. Da sollte es keine Rechteprobleme geben (oder ?)
Danke weiterhin für Mithilfe
Delete - So 16.01.11 17:09
Ich meinte eigentlich die Zugriffsrechte auf den Ordner.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!