Probleme beim Recovery-CD programmieren
-
Mistil schrieb:
Hi. Ich bin gerade dabei C zu lernen, und will mir nebenbei eine Recovery-CD schreiben

Oh Gott!
Mistil schrieb:
und zum anderen die String-Variable in eine Konstante umzuwandeln, die die Funktion akzeptiert.
Wenn du std::string verwendest probier mal "str.c_str()" statt nur "str" an die Funktion zu übergeben.
Wenn du CString verwendest dann sollte es auch ohne gehen, ansonsten nimm "str.GetString()" statt "str".Mistil schrieb:
MoveFile funktioniert komischerweise auch con d: nach c: wenn ich die Pfade als String fest eingebe.
CopyFile kopiert bei mir nicht über die Festplatte hinaus, und auch nur mit fest eingegebenem String.Sowohl MoveFile(Ex) als auch CopyFile(Ex) funktionieren zwischen verschiedenen Laufwerken.
Mistil schrieb:
Oder gibt es vielleicht eine Funktion, mit der ich ganze Ordner kopieren kann? Dann wäre es am einfachsten

Da bestimmt noch weitere Probleme bei meinem kleinen Projekt auftreten, habe ich den Thread zu dem Projekt geöffnet und nicht zu dem einen Problem. So muss ich für die nächsten Probleme nicht immer neue Threads öffnen.
Für Kopieren kenne ich nix. Für Verschieben kannst du MoveFile(Ex) verwenden.
Achja, poste auf keinen Fall irgendwelchen Beispielcode, damit man sehen könntest was du probiert hast.
-
hustbaer schrieb:
Mistil schrieb:
Hi. Ich bin gerade dabei C zu lernen, und will mir nebenbei eine Recovery-CD schreiben

Oh Gott!
Super Begrüßung
(ganz nach dem Motto: noch so ein Idiot, der keine Ahnung hat und trotzdem die Welt verändern will)
Is ja nicht so, dass ich das ganze machen will, um das gelernte anzuwenden und noch mehr dazu zu lernen. Irgendwann isses halt langweilig immer nur Taschenrechner zu basteln.Ich wusste leider nicht, dass du einen Beispielcode brauchst, weil ich nur auf der Suche nach einer Funktionwar, die ich verwenden kann und nicht nach einem Fehler im Code. Da ich aber wohl doch etwas falsch gemacht habe bitte:
#include <stdio.h> #include <windows.h> main() { char sourcefile[81]="Icons\\icon.ico"; /*liegt auf d: im gleichen Ordner wie mein Program*/ char targetfile[81]="c:\\test\\Icons\\icon.ico"; CopyFile(sourcefile, targetfile, 0); return 0; }Das ganze habe ich einmal mit den direkten Strings in "" (also zum Beispiel: "Icons\\icon.ico") versucht und einmal mit den Stringvariablen. Von d: auf c: konnte ich die Datei garnicht kopieren, von d: auf d: nur, wenn ich die Strings angegeben habe.
MoveFile schafft es über die Laufwerksgrenzen hinaus, allerdings "bewegt" MoveFile die Datei, und das auch nur wenn ich die dierekten Strings eingebe. Bei Angabe der Variablen passiert nix.Was is denn eigentlich std::string? Der Ausdruck sagt mir leider nichts.
Edit:
Ich habe eben beide Varienten versucht. Also einmal der Funktion sourcefile und targetfile als sourcefile.c_str() und targetfile.c_str() zu übergeben, und dann auch mal mit GetString() statt c_str. Beides mal habe ich den Fehler "error: request for member 'c_str' (oder 'GetString') in something not a structure or union"
Falls es von interesse ist, ich benutze Code::Blocks als Entwicklungsumgebung.
-
1. Es gibt einfacheres für Newbies als Recovery-CDs.
Ich verstehe den Kommentar von Hustbaer. Das scheint mir genauso als ob ein Anfänger im Modellbau gleich einen Helikopter mit 120 cm Spannweite und 30 Servomotoren bauen will.
2. Das die Datei in dem selben Verzeichnis liegt heißt nichts. Für ein Programm gibt es so etwas wie ein Working Directory, dass bei Programmstart festgelegt wird. D.h. relative Pfade werden immer vom Working-Directory aus gerechnet nicht vom Progranmmverzeichnis aus.
3. Wenn Dir std::string nichts sagt rate ich Dir dringend zu einem Tutorial zu C++ oder zu Google.
-
Die von dir gefundene Funktion CopyFile gehört zu WinAPI (siehe Forum) und lässt sich natürlich auch ohne aufwändige Kenntnis diverser String-Implementierungen verwenden. Da du CB benutzt, ist UNICODE glücklicherweise nicht der Default und du kannst mit normalen Stringliteralen arbeiten.
Sicherstellen musst du zuvor mindestens die Existenz des Zielpfades (was du nicht machst), und Fehlerbehandlung machst du auch nicht (wobei du den Fehler genauer mitgeteilt bekommst), dann brauchst du auch keine Aussagen wie "funktioniert nicht" o.ä. hier abliefern.
Auch benötigst du sicherlich Funktionen zum verzeichnisweisen Lesen von Dateinamen, auch hier wirst du in WinAPI fündig.
-
Mistil schrieb:
Oder gibt es vielleicht eine Funktion, mit der ich ganze Ordner kopieren kann? Dann wäre es am einfachsten
SHFileOperation
-
Martin Richter schrieb:
1. Es gibt einfacheres für Newbies als Recovery-CDs.
Ich verstehe den Kommentar von Hustbaer. Das scheint mir genauso als ob ein Anfänger im Modellbau gleich einen Helikopter mit 120 cm Spannweite und 30 Servomotoren bauen will.Wie oben geschrieben soll das ja auch keine echte Recovery-CD sein, sondern das Program soll Dateien an bestimmte Stellen kopieren und installations Programme auf der CD ausführen. Ich will ja nicht gleich ein Betriebssystem programmieren.
Martin Richter schrieb:
2. Das die Datei in dem selben Verzeichnis liegt heißt nichts. Für ein Programm gibt es so etwas wie ein Working Directory, dass bei Programmstart festgelegt wird. D.h. relative Pfade werden immer vom Working-Directory aus gerechnet nicht vom Progranmmverzeichnis aus.
OK. Falsch ausgedrückt. Aber immerhin funktioniert es, wenn ich den Pfad relativ zu dem Ort angebe, an dem das Program erstellt wurde. Hab ichs wohl unwissentlich richtig gemacht.
Martin Richter schrieb:
3. Wenn Dir std::string nichts sagt rate ich Dir dringend zu einem Tutorial zu C++ oder zu Google.
Warum soll ich mir ein Tutorial zu C++ zulegen, wenn ich in C programmiere???
@Wutz:
Wieso soll ich den Zielpfad nicht sicher gestellt haben? Nur weil es im Beispiel nicht gezeigt ist? Darüber mache ich mir später gedanken, ich suche erst mal eine Funktion, die es schafft meine Daten zu kopieren und da finde ich es ausreichend, wenn ich vorher mit meinem Dateimanager dafür sorge, dass der Zielpfad vorhanden ist.Wutz schrieb:
...dann brauchst du auch keine Aussagen wie "funktioniert nicht" o.ä. hier abliefern.
Wo liegt da denn jetzt wieder das Problem??? Wenn das Program ohne Probleme durchläuft, aber das was es machen soll nicht erledigt (sprich die Datei nicht kopiert). Wie würdest du das nennen?
-
Benutze den Debugger, checke Return Werte / GetLastError usw.
Das hilft.
-
Nimm bitte BartPE und schreibe dazu ein "normales" Windows Programm!
Damit kannst Du dann alles machen was Du willst!@ADD: Oder schau mal hier nach; da gibt es auch aktuelle Varianten: http://reboot.pro/forum/22/
-
Mistil schrieb:
Wutz schrieb:
...dann brauchst du auch keine Aussagen wie "funktioniert nicht" o.ä. hier abliefern.
Wo liegt da denn jetzt wieder das Problem??? Wenn das Program ohne Probleme durchläuft, aber das was es machen soll nicht erledigt (sprich die Datei nicht kopiert). Wie würdest du das nennen?
Gehe davon aus, dass die viele Jahre existierende WinAPI-Funktion CopyFile fehlerfrei arbeitet, dazu ist es hilfreich, sich die vollständige Spezifikation dieser Funktion anzuschauen und insbesondere, wie Fehler angezeigt werden.
Wenn also irgendetwas in DEINEM Programm nicht nach DEINEN Vorstellungen läuft, liegt es ausschließlich an DEINEM Code bzw. DEINER aktuellen Systemumgebung.
Da brauchst du dich auch nicht zu echoffieren, wenn hier jemand sich die Mühe machst, in seiner Freizeit und kostenlos über den von dir zweifellos nebulös formulierten Fehler Gedanken zu machen oder dir seine Favoriten-Sprache oder Bibliothek aufs Auge zu drücken.
Aber du hast natürlich soweit recht, dass die WinAPI zunächstmal reines C ist und man demzufolge auch alles diesbezügliche in C realisieren kann.
-
Mistil schrieb:
Martin Richter schrieb:
3. Wenn Dir std::string nichts sagt rate ich Dir dringend zu einem Tutorial zu C++ oder zu Google.
Warum soll ich mir ein Tutorial zu C++ zulegen, wenn ich in C programmiere???
Ja, sorry, das war mein Fehler. Du hast ja ganz klar "C" geschrieben und nicht "C++".
Davon abgesehen.
-
Du solltest lernen etwas selbständiger zu sein. Bevor du das nächste mal fragst was X ist bitte gib einfach X in Google ein und drücke auf "Suchen". Herauszufinden was z.B. std::string ist, sollte weniger als eine Minute in Anspruch nehmen.
-
Ich sehe zwei sinnvolle Möglichkeiten: such dir eine andere Sprache aus oder überleg dir ein anderes Projekt. C ist für das was du beschrieben hast IMO das falsche Werkzeug, da wären eher noch Batchfiles gefragt.
-
-
Lass Ihn doch, du schlaumeier. Er will ja C lernen und nicht Batch!
-
Als erstes mal ein frohes neues Jahr euch allen. Ich hoffe, ihr seid gut rein gerutscht.

@Wutz:
Ich will ja garnicht sagen, dass die Funktion einen Fehler hat. Aber wie in meinen ersten Posts schon gesagt habe ich das Problem, dass die Funktion "so wie ich sie eingebaut habe" nicht funktioniert. Genau so, wie ich den Fehler in der übergabe der Pfade an die Funktion vermute (wie gesagt, wenn ich String-Konstanten angebe, geht es). Daher meine ich den Fehler lokalisiert zu haben (die Returnwerte, die ich mir anzeigen lasse, sind auch die, welche ich erwarte) und frage mich, warum ich weiter suchen soll. Um den Fehler zu beseitigen suche ich (wie auch schon am anfang geschrieben) nach einer möglichkeit der Funktion meine Stringvariablen so zu übergeben, dass sie läuft oder nach einer anderen Funktion die die Variablen akzeptiert.hustbaer schrieb:
...
Davon abgesehen.-
Du solltest lernen etwas selbständiger zu sein. Bevor du das nächste mal fragst was X ist bitte gib einfach X in Google ein und drücke auf "Suchen". Herauszufinden was z.B. std::string ist, sollte weniger als eine Minute in Anspruch nehmen.
-
Ich sehe zwei sinnvolle Möglichkeiten: such dir eine andere Sprache aus oder überleg dir ein anderes Projekt. C ist für das was du beschrieben hast IMO das falsche Werkzeug, da wären eher noch Batchfiles gefragt.
-
ich bin des Googelns durchaus mächtig. Ich habe tatsächlich innerhalb weniger minuten herausgefunden was std::string im zusammenhang mit c++ ist. Da es hier aber um c ging und du garantiert mehr darüber weist als ich (sonst wären die Rollen hier wohl vertauscht) habe ich dich gefragt, weil ich nicht herausfinden konnte, was std::string in verbindung mit c zu bedeuten hat.
-
Ich finde es schade, dass ich mit c keine Programme schreiben kann, die Dateien kopieren. Aber Danke für den Tip. Ich habe mein Program jetzt so verändert, dass es den eigentlichen Kopiervorgang an eine Batch-Datei weitergibt. Das kopieren dauert jetzt zwar etwas länger, aber immerhin funktioniert es jetzt.
trotzdem wäre ich immernoch dankbar, wenn mir einer einen Tipp geben könnte, wie ich mein kleines gepostetes "Beispiel-"Program zum laufen bringe (unter optimalen Vorraussetzungen, sprich zielverzeichniss und quelldatei vorhanden...), damit das Kopieren schneller geht.
-
-
Also, ich habe mal dein kleines Programm eingegeben und getestet.
Mit meinen beiden am weitesten entfernten Laufwerken, damit er richtig weit bewegen muss. Und habe absichtlich die Dateiendung im Ziel verändert, um zu sehen ob er auch das macht.
Und es klappt einwandfrei. Datei als auch Inhalt wurden komplett bewegt und umbenannt.
Es klappt allerdings nicht, wenn bereits eine Datei mit dem gleichen Zielnamen im Zielordner vorhanden ist. Ansonsten klappt es wunderbar.#include <stdio.h> #include <windows.h> main() { char sourcefile[81]="i:\\intel\\Notice.txt"; char targetfile[81]="c:\\juppijupp.dat"; MoveFile(sourcefile, targetfile); return 0; }
-
Also das kapier ich jetzt net.
Bei mir gehts grad auch mit dem kleinen Program. Da muss ich wohl morgen nochmal genauer suchen, warum es erst net geht und dann doch. Hatte das vor dem Posten extra nochmal überprüft, ob es nicht doch läuft.

Eben ist mir was eingefallen. Ich habe die Dateinamen nach dem Zählen der Dateien in einer Datei zwischengespeichert
. Könnte es sein, dass meine Lesefunktion, die die Namen jeweils einzeln aus der Datei holt das '\n' Zeichen mitgelesen und dann später auch in den Dateipfad mit eingebaut hat?
Sieht wohl so aus, als ob ich mich entschuldigen müsste. Der Fehler ist zwar an der erwarteten Stelle, aber nicht der Fehler, für den ich eine Lösung gesucht habe.
Ich werde euch morgen mal den Code dazu posten, vielleicht habe ich ja auch noch einen anderen Fehler drin.Aber warum die Funktion die ganze Zeit nicht funktioniert hat und jetzt auf einmal doch, kann ich mir trotzdem nicht erklären.
-
Aber warum die Funktion die ganze Zeit nicht funktioniert hat und jetzt auf einmal doch, kann ich mir trotzdem nicht erklären.
Weil DEIN Code die ganze Zeit Mist baut, und nicht "die Funktionen".
-
So. Es lag tatsächlich am new-line-Zeichen. Jetzt funktioniert auch meine CopyFile-Funktion wie sie soll.
Da jetzt alles unter optimalen Bedingungen funktioniert, dürfte sich im Code erstmal kein Fehler mehr verstecken. Jetzt mache ich mich an die Sicherheitsvorkehrungen. Der folgende Code ist meine Zählfunktion:#include <dirent.h> #include <stdio.h> #include <windows.h> #define MAXENTRY 1024 main() { DIR *myDir; FILE *temp_p; char *dirName; struct dirent *entry; char *dirNames[MAXENTRY]; int i=0; dirName="d:\\test\\"; temp_p=fopen ("c:\\tempfile.txt", "w"); if (!(myDir=opendir(dirName))) { printf("Verzeichnis kann nicht geoeffnet werden\n"); exit(1); } while (entry=readdir(myDir)) { dirNames[i++]=strdup(entry->d_name); fprintf(temp_p, "%s\n", entry->d_name); } closedir(myDir); fclose(temp_p); return i; }Ich bräuchte eine Möglichkeit zwischen Verzeichnissen und Dateien zu unterscheiden, dass nur Dateinamen in die Temp-Datei geschrieben werden. Später kann ich damit dann die Funktion dann auch so umschreiben, dass sie rekursiv aufgerufen wird.
Um den Zielpfad beim kopieren sicher zu stellen habe ich vor, die erste Datei auf den jeweiligen Zielpfad mithilfe einer Batchdatei zu kopieren. Dabei wurde bis jetzt immer der Zielpfad generiert.
Die Char-Größen für Strings werde ich noch dynamisch allokieren, sobald ich das letzte Kapitel meines Tutorials durch habe.
Danach ist das Thema kopieren durch.Als nächstes wäre dann das ausführen diverser Installationsprogramme zu erledigen. Wie kann ich Befehle an das Program weiter geben? z.b. ganz banal wenn mich das Installationsprogramm fragt, ob ich die Lizenzbedingungen annehme. Wie kann ich das über mein Programm bestätigen? Gibt es da eine Möglichkeit in C?
Danke schonmal.
Edit:
OK, also dass die Sache mit den Installationsprogrammen in c nicht geht, habe ich eben herausgefunden. Da muss ich also nach einer anderen Möglichkeit suchen, aber die Zählfunktion würde ich trotzdem gerne noch verfeinern.
Nimmt mir ja schonmal ein bischen Arbeit weg.
-
Mistil schrieb:
Um den Zielpfad beim kopieren sicher zu stellen habe ich vor, die erste Datei auf den jeweiligen Zielpfad mithilfe einer Batchdatei zu kopieren.
Oh Gott hilf!
-
Na hier bekomme ich ja hauptsächlich Kritik zu hören, also muss ich mit dem was ich habe nach Lösungen suchen.
-
Zerleg den Pfad in Laufwerk, Verzeichnis, Verzeichnis ... Verzeichnis, Dateiname, und leg dann in einer Schleife alle Verzeichnisse an.
Das geht in C, ganz ohne Batchfiles.
Eine relativ einfache Möglichkeit das zu machen wäre:
void CreateDirectories(char const* path, bool isDirectory); void CreateDirectoriesImpl(char* path, bool isDirectory); void CreateDirectories(char const* path, bool isDirectory) { // string sicherheitshalber kopieren, wir werden den nämlich modifizieren char* pathCopy = malloc(strlen(path) + 1); strcpy(pathCopy, path); CreateDirectoriesImpl(pathCopy, isDirectory); free(pathCopy); } void CreateDirectoriesImpl(char* path, bool isDirectory) { int pos = finde_letzten_slash_oder_backslash(path); if (pos != nix_gefunden) { char backup = path[pos]; // backup des slash/backslash machen path[pos] = 0; // alles wegschneiden was nach dem letzten slash/backslash kommt (inklusive) // wir rufen uns selbst rekursiv auf um alle verzeichnisse VOR "unserem pfad" anzulegen CreateDirectoriesImpl(path, true); // slash oder backslash wiederherstellen path[pos] = backup; // wenn "unser" ungekürzter pfad ein verzeichnis war, muss das auch noch angelegt werden if (isDirectory) ::CreateDirectoryA(path, 0); } } void Foo() { char const* sourcePath = "c:\\test.txt"; char const* destPath = "c:\\foo\\bar\\baz\\qux\\quux\\test.txt"; CreateDirectories(destPath, false); CopyFile(sourcePath, destPath, true); }
-
Das is doch mal ne Antwort. Danke dir.
Ich dachte, es würde vielleicht einen Fehler oder so geben, wenn ich einen Ordner anlegen möchte, der schon existiert. Deswegen wollte ich das nicht ohne vorhergehende Prüfung machen. Da ich aber nicht wusste, wie ich einen Pfad auf existenz prüfe, wollte ich mir anderst aus der Patsche helfen.
Danke dir. Ich werde morgen gleich mal versuchen, das in meinen Code mit einzubauen.
