Laden...

SHFileOperation kopiert nicht von CD-Laufwerk

Erstellt von -acid- vor 18 Jahren Letzter Beitrag vor 18 Jahren 4.873 Views
-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren
SHFileOperation kopiert nicht von CD-Laufwerk

Hallo Leute,

ich versuche mich gerade an dem Artikel bzw. an dessen Bespielcode:

http://www.pinvoke.net/default.aspx/shell32.SHFileOperation

Leider funktioniert bei mir das Kopieren von einer CD nicht. Warum? Ich könnte mir vorstellen das irgendein Flag falsch gesetzt ist...

Mein Code:

Shellworks fo = new Shellworks();
fo.pFrom = @"D:\";
fo.pTo = @"C:\TEMP";
fo.wFunc = Shellworks.FO_Func.FO_COPY;
fo.Execute();
49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

wie ist der Rückgabewert? Gibt es einen Fehlercode (LastError?) oder Fehlermeldung? Was ist der Effekt?

herbivore

I
1.739 Beiträge seit 2005
vor 18 Jahren

@"C:TEMP";?
deshalb?

irgendwie fehlt der Backslash.

Edit: ok, wurde wohl vom Forum geschluckt.

Hast du die Klasse so übernommen? Welche Parameter?

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

wie ist der Rückgabewert? Gibt es einen Fehlercode (LastError?) oder Fehlermeldung? Was ist der Effekt?

Die Klasse aus dem Beispiel habe ich nicht verändern. Ich rufe sie lediglich mit dem
Code auf:

public partial class Form1 : Form
    {
        private InteropSHFileOperation fo;
        public Form1()
        {
            InitializeComponent();

            fo = new InteropSHFileOperation();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            fo.pFrom = @"G:\\"; // CD
            fo.pTo = @"F:\\TEMP"; // Lokal
            fo.wFunc = InteropSHFileOperation.FO_Func.FO_COPY;
            fo.Execute();
        }
    }

Dann kommt diese Meldung (bei normalen Laufwerken geht es, nur halt bei meinem CD-Laufwerk nicht):

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

als Quelle hast du ein Verzeichnis und keine Datei angegeben.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Ah. Wie wandle ich das denn um damit ich einen kompletten Ordner kopieren kann? Weil bei lokaler Quelle und Ziel geht es mit Ordnern.

M
115 Beiträge seit 2003
vor 18 Jahren

Ich hab das ganze mal mit der ShellLib von Codeproject ausprobiert.
Funktionierte einwandfrei.

Gernot Melichar

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Damit habe ich auch angefangen... Hm. Also muss ich dann mein zu kopierendes Verzeichnis rekursiv durchlaufen und den Filename an die ShellCopy Methode weitergeben? Oder gibt es eine Möglichkeit?

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

hast du denn mal probiert, ob es funktioniert eine einzelne Datei von CD zu kopieren? Wenn ja, wäre der rekursive Weg ja eine relative einfache Möglichkeit. Ich kennen das von APIs eigentlich nur so, dass sie nur einzelne Dateien kopieren können, und hätte daher gleich selbst rekursiv programmiert.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Also er kopiert einzelne Dateien von CD, ja. Das heißt er kommt einfach nicht mit Verzeichnissen klar. Denke dann kann ich es auch manuell machen sprich selbst programmieren.

Danke für eure Hilfe 🙂

M
115 Beiträge seit 2003
vor 18 Jahren

Nochmals:
Ich habe die ShellLib von Codeproject verwendet.


            ShellLib.ShellFileOperation op = new ShellLib.ShellFileOperation();

       

            string[] source = {@"e:\\beispiele\kapitel 01" };
            string[] dest =  {@"d:\\test" };

            op.OwnerWindow = this.Handle;
            op.Operation = ShellLib.ShellFileOperation.FileOperations.FO_COPY;
            op.SourceFiles = source;
            op.DestFiles = dest;
            
            bool ret=op.DoOperation();

Wurde einwandfrei kopiert von CD mit Unterverzeichnissen.Und bei Dir
funktioniert es nicht?

Gernot Melichar

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Meli ich weiß. Du hast aber das Problem nicht verstanden: Er kopiert zwar Verzeichnisse komplett, aber nicht wenn ich direkt als Quelle das CD-LAufwerk zb. "D:" angebe.

M
115 Beiträge seit 2003
vor 18 Jahren

Ahh, dann versuchs mit:


string[] source = {@"e:\\*.*" };


So klappts bei mir.

Gernot Melichar

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Hui toll 🙂

Dank dir Meli. Ich habe es ja zum Großteil schon selbst gemacht, habe aber mit den ganzen Features wie Ersetzen ja/nein, alle, etc... noch Probleme gehabt und wuste nicht wie ich die ganzen Funktionen schreiben soll. Dann nehme ich das 👍

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

*.* ist Dos-Steinzeit und arbeitet bei Windows nicht wie erwartet.

Nimm einfach nur *

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Danke herbivore 👍

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Habe mir gerade eine Demo Application geschrieben. Dort funzt es:

//Quelle wählen
private void button2_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fb = new FolderBrowserDialog();

            if (fb.ShowDialog() == DialogResult.OK)
            {
                string[] SourcePath = { fb.SelectedPath + "*" };
                this.sc.SourceFiles = SourcePath;
            }
        }

//Ziel wählen
        private void button3_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fb = new FolderBrowserDialog();

            if (fb.ShowDialog() == DialogResult.OK)
            {
                string[] DestPath = { fb.SelectedPath };
                this.sc.DestFiles = DestPath;
            }
        }

Dort habe ich dann auch noch noch Buttn der das Kopieren ausführt. Den gleichen Code habe ich in eine andre Anwendung übernommen und bekomme beim Abbrechen des Kopierendialogs folgenden Fehler:

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at fastInstall.plgnDataSource.button3_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Könnt ihr mir helfen?

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

übersetz mal im Debug-Modus. Dann siehst du die genaue Zeile, in der die Exception auftritt. Da das in deiner eigene Methode ist, sollte die Ursache nicht schwer zu finden sein.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

übersetz mal im Debug-Modus.

Was heißt das? Ich benutze bereits den Debugmodus. Dort wird eine dll erstellt, die in meinem Hauptprojekt referenziert wird. Gibt es eine bessere Möglichkeit zu debuggen um genau die Zeile angezeigt zu bekommen?

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

ich bin davon ausgegangen, dass fastInstall.plgnDataSource.button3_Click eine Methode von dir ist. Und wenn die zugehörige Assembly im Debug-Modus übersetzt wäre, dann müsste dahinter eine Zeilennummer angezeigt werden.

Wenn die Methode gar nicht von dir ist, vergiss meinen Beitrag.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Also ich habe nochmal geschaut. Komischerweise gehts im Debugmodus aus VS heraus ohne Fehler. Der Fehler tritt nur beim Einzelaufruf der exe auf. Wie kann ich denn den Fehler lokalisieren? Achja: Der Click des Buttons ist einfach nur ein stink normales Buttonevent, welche die Kopierroutine aufruft. Der Code ist also genau der gleiche wie unten...

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

Der Fehler tritt nur beim Einzelaufruf der exe auf. Wie kann ich denn den Fehler lokalisieren?

Da gibt es viele Möglichkeiten. Meine wäre, das Programm als Konsolen-Anwendung zu übersetzen und die Exception (und natürlich den StackTrace) einfach mit Console.WriteLine auszugeben.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Ah. StackTrace... habe den mal ausgeben lassen:

try
            {
                //this.btnCopy.Enabled = false;
                this._ShellCopy.OwnerWindow = this.Handle;
                this._ShellCopy.Copy();
                //this.btnCopy.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + " \r\n\r\n" + ex.StackTrace);
            }

Wenn ich nun die zwei Zeilen, die den Button erst deaktiviert und dann wieder aktiviert, ausblende geht es. Ich verstehe aber nicht was ich falsch mache bzw. warum es dann nicht funktioniert wenn die zwei Zeilen wieder eingebunden werden.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

na vermutlich doch, weil this.btnCopy null ist.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Habe die Zeilen weggelassen. So geh es jetzt. Bin aber noch wie vor am überlegen ob ich nicht doch - wie herbivore schon sagte - zu meiner alten eigenen Kopiermethode zurückgreife. Die ist zwar nicht so konfortabel, aber ich habe ein Dialogfenster, damit der User nicht mehr auf die Hauptform zugreifen kann und ich habe mehr Kontrolle über das was ich anzeige und mache. Außerdem bin ich unabhängig von WinApis.

Danke für eure Hilfe 🙂

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

auch hier verstehe ich nicht ganz den Zusammenhang. Hast du denn mal geguckt, ob this.btnCopy null ist? Wenn ja, dann musst du doch nur diese Variable auf den richtigen Button setzen und schon sollte es gehen.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Ja sie ist null.

a) Wie wie setze ich diese Variable auf den richtigen Button? Mit this.btnCopy = this.btnCopy; ?!
b) Wie ich bereits sagte, spricht Einiges dafür eine eigene Methode zu verwenden. Daher denke ich ist es wirklich sinnvoller mich nochmal mit meiner eigenen Kopierroutine zu beschäftigen.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

a) Wie wie setze ich diese Variable auf den richtigen Button?

Durch Zuweisung. 🙂
Der Button wird mit new erzeugt. Den Rückgabe dieses news musst du direkt oder indirekt an this.btnCopy zuweisen.

Mit this.btnCopy = this.btnCopy; ?!

Nein, das weist ja nur die Variable an sich selbst zu. Wenn die vorher null ist, ist sie es nacher auch.

herbivore

-
-acid- Themenstarter:in
885 Beiträge seit 2004
vor 18 Jahren

Ah also erzeuge ich einfach eine neue Buttoninstanz names btnCopy. Ok danke 🙂

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo -acid-,

nur wenn es diese Instanz noch nicht gibt, sonst hättest du ja zwei Instanzen. Wenn es die Instanz schon gibt, musst du nur dafür sorgen, dass sie an btnCopy zugewiesen wird.

herbivore