Autor Beitrag
ezra_k
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Mi 12.01.11 18:44 
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:

ausblenden 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 user profile iconChristian S.: C#-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19313
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 12.01.11 18:52 
Dann versuche es mit der API. SHFileOperation benutzt der Explorer.
ezra_k Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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:

ausblenden volle Höhe 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;
           //public short 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;  // Copy
           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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19313
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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:
www.codeproject.com/...ll/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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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

ausblenden 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:

ausblenden volle Höhe 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;
           
           //[MarshalAs(UnmanagedType.LPWStr)]
           public string pFrom;
           
           //[MarshalAs(UnmanagedType.LPWStr)]
           public string pTo;
           
           //[MarshalAs(UnmanagedType.U2)]
           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;  // Copy
           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
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: So 16.01.11 17:03 
Zitat:
Dann werte doch mal den Rückgabewert aus

Da kommt 124 raus...

Zitat:
und rufe mal GetLastError

ausblenden 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
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 16.01.11 17:09 
Ich meinte eigentlich die Zugriffsrechte auf den Ordner.