Autor Beitrag
chris_davidi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Do 21.08.03 10:49 
Hallo...

Habe schon einige Threads durchsucht, aber nichts gefunden. Weiß jemand, wie ich eine Diskette formatieren kann? Brauche den Befehl dazu, so dass, wenn ich mein Programm starte zuerst geschaut wird, ob eine Diskette vorhanden ist und wenn ja, wird diese formatiert.

Danke für eure Antworten.
Chris
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.08.03 12:26 
Ich bin nicht sicher, ob dir das reicht, aber die einfachste Möglichkeit ist, die Funktion des Explorers zu nutzen: SHFormatDrive. Das ist so, wie du´s kennst: Diskette rein -> Rechtsklick -> Formatieren -> Fenster ... voilà ... :)

Kannst ja mal schauen, ob das für dich ausreichend ist. Minimum ist laut Microsoft aber Win 2000.
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Do 21.08.03 12:33 
Danke für deine Antwort. Kann man es aber auch so machen, dass ich in einem Formular einen Button anlege mit dem Titel "formatieren" und wenn ich auf den klicke, dass sich die Diskette formatiert, ohne dass ein Fenster aufspringt oder so?
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.08.03 14:08 
Mit der genannten Systemfunktion ist das nicht möglich. Ich vermute mal, dass da Sicherheitsgründe auch eine Rolle spielen. Und das ist ja auch okay. Gerade bei solchen Sachen bin ich auch lieber für eine Abfrage zuviel als zuwenig.

Wenn sich Leute "versehentlich" ihre Disketten formatieren, dann sagen sie ja auch nicht: Upps, meine Schuld, sondern sie kommen zu dir und meckern, weil sie von deinem Programm nicht genügend gewarnt wurden. :)

Eine andere Möglichkeit zum Formatieren kenne ich im Augenblick aber leider nicht. Sorry.
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.08.03 14:12 
Übrigens, für alle, die´s interessiert:
MathiasSimmack hat folgendes geschrieben:
Minimum ist laut Microsoft aber Win 2000.

Windows 98 -> "shell32.dll" -> Version 4.72.x.x -> Formatierungsdialog funktioniert auch. Ist seitens Microsoft nicht dokumentiert, aber das ist nicht wirklich was neues. :)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.08.03 14:32 
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.08.03 15:53 
Was willst du uns damit sagen? Außer, dass ich an dem Artikel erkenne, wie alt er ist - denn mittlerweile wird die Funktion sowohl im PSDK als auch in der Headerdatei erwähnt. :)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 21.08.03 20:49 
Ups, ich dachte das wäre es, was ihr sucht. *Rennt mit dem Artiken in der Hand aufgeregt zu Assarbad*
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Fr 22.08.03 09:19 
Habe nun noch etwas rumprobiert, kann mir jemand genauen Code geben, wie ich zumindest das einbinde, wie als wenn ich im Windows beim Laufwerk mit rechts klicke und dann formatiere?

Komme einfach nicht drauf, wäre nett, wenn mir jemand helfen könnte und den Code postet... Danke.. :)

Gruss
Chris
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Fr 22.08.03 12:37 
Habe nun eine passende Funktion gefunden.

Schaut mal bitte: delphi.advis.de/syst/17.html

Aber wie binde ich diese ein, dass die Funktion ausgeführt wird, wenn ich auf einen Button klicke? Kann es mal jemand bei sich probieren und hier posten? Wäre total nett. :)

Grüße
Chris
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.08.03 12:45 
Vereinfacht:
ausblenden volle Höhe Delphi-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:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
unit blablabla;

interface

(*
 * The SHFormatDrive API provides access to the Shell
 *   format dialog. This allows apps which want to format disks
 *   to bring up the same dialog that the Shell does to do it.
 *
 *   This dialog is not sub-classable. You cannot put custom
 *   controls in it. If you want this ability, you will have
 *   to write your own front end for the DMaint_FormatDrive
 *   engine.
 *
 *   NOTE that the user can format as many diskettes in the specified
 *   drive, or as many times, as he/she wishes to. There is no way to
 *   force any specififc number of disks to format. If you want this
 *   ability, you will have to write your own front end for the
 *   DMaint_FormatDrive engine.
 *
 *   NOTE also that the format will not start till the user pushes the
 *   start button in the dialog. There is no way to do auto start. If
 *   you want this ability, you will have to write your own front end
 *   for the DMaint_FormatDrive engine.
 *
 *   PARAMETERS
 *
 *     hwnd    = The window handle of the window which will own the dialog
 *               NOTE that unlike SHCheckDrive, hwnd == NULL does not cause
 *               this dialog to come up as a "top level application" window.
 *               This parameter should always be non-null, this dialog is
 *               only designed to be the child of another window, not a
 *               stand-alone application.
 *     drive   = The 0 based (A: == 0) drive number of the drive to format
 *     fmtID   = The ID of the physical format to format the disk with
 *               NOTE: The special value SHFMT_ID_DEFAULT means "use the
 *                     default format specified by the DMaint_FormatDrive
 *                     engine". If you want to FORCE a particular format
 *                     ID "up front" you will have to call
 *                     DMaint_GetFormatOptions yourself before calling
 *                     this to obtain the valid list of phys format IDs
 *                     (contents of the PhysFmtIDList array in the
 *                     FMTINFOSTRUCT).
 *     options = There is currently only two option bits defined
 *
 *                SHFMT_OPT_FULL
 *                SHFMT_OPT_SYSONLY
 *
 *               The normal defualt in the Shell format dialog is
 *               "Quick Format", setting this option bit indicates that
 *               the caller wants to start with FULL format selected
 *               (this is useful for folks detecting "unformatted" disks
 *               and wanting to bring up the format dialog).
 *
 *               The SHFMT_OPT_SYSONLY initializes the dialog to
 *               default to just sys the disk.
 *
 *               All other bits are reserved for future expansion and
 *               must be 0.
 *
 *               Please note that this is a bit field and not a value
 *               and treat it accordingly.
 *
 *   RETURN
 *      The return is either one of the SHFMT_* values, or if the
 *      returned DWORD value is not == to one of these values, then
 *      the return is the physical format ID of the last succesful
 *      format. The LOWORD of this value can be passed on subsequent
 *      calls as the fmtID parameter to "format the same type you did

 *      last time".
 *
 *)


function SHFormatDrive(wnd: HWND; drive: UINT; fmtId: UINT;
  options: UINT): dword; stdcall;

//
// Special value of fmtID which means "use the default format"
//
const
  SHFMT_ID_DEFAULT    = $FFFF;

//
// Option bits for options parameter
//
  SHFMT_OPT_FULL      = $0001;
  SHFMT_OPT_SYSONLY   = $0002;

//
// Special return values. PLEASE NOTE that these are DWORD values.
//
  SHFMT_ERROR         = $FFFFFFFF;     // Error on last format, drive may be formatable
  SHFMT_CANCEL        = $FFFFFFFE;     // Last format was canceled
  SHFMT_NOFORMAT      = $FFFFFFFD;     // Drive is not formatable

implementation

const
  shell32 = 'shell32.dll';

function SHFormatDrive; external shell32 name 'SHFormatDrive';

end.

Benutzung:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
uses
  blablabla;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SHFormatDrive(self.Handle,
    0 { für Laufwerk A, B = 1, C = 2, ... usw. },
    SHFMT_ID_DEFAULT,
    0 { oder SHFMT_OPT_FULL, s. Beschreibung }
  );
end;

Angabe ohne Gewähr, weil aus´m Kopf. (Na ja, nicht alles ... :wink:)
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Fr 22.08.03 12:47 
Okay danke. Bräuchte aber die Einbindung des anderen Codes, weil sich dort kein weiterer Dialog öffnet. Dieser formatiert sofort die Diskette... Muss mir nämlich ein Programm schreiben, welches die eingelegte Diskette formatiert und wenn das fertig ist mit den neuen Daten beschreibt, alles mit einem Klick. Daher brauche ich die Einbung des Codes von delphi.advis.de/syst/17.html . So dass dieser ausgeführt wird, wenn ich auf einen Button klicke. Hast du dafür eine Idee?
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.08.03 12:52 
Es würde helfen den korrekten Link zu posten:
Zitat:

Die Seite wurde nicht gefunden.
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Fr 22.08.03 12:53 
Doch, es ist der richtige Link. Bei mir geht er...

Poste mal hier den Inhalt der Seite:
Zitat:
Dieses Beispiel (von Gerd Kayser) demonstriert das "stille" Formatieren eines Datenträgers. Die Routine ruft das DOS-Programm Format.com auf, darum erscheint kein Windows-Formatier-Dialog, es wird auch kein DOS-Fenster geöffnet. Nach dem Aufruf des Formatierprogramms wartet die Routine, bis das Formatieren beendet ist und prüft schließlich noch, ob die Formatierung erfolgreich war:

ausblenden volle Höhe Delphi-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:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
function TMainform.Diskette_formatieren(Laufwerk: String): Integer;
var Befehl : String;
    Datei : TextFile;
    TempDateiName : Array [0..255] of Char;
    TempVerzeichnis : Array [0..255] of Char;
    StartupInfo : TStartupInfo;
    ProcessInfo : TProcessInformation;
    SektorenProCluster : Integer;
    BytesProSektor : Integer;
    FreieCluster : Integer;
    ClusterInsgesamt : Integer;
    Temp : Integer;
begin
  // Datei zum Beantworten der Abfragen von FORMAT.EXE im Temp-Verzeichnis anlegen.
  GetTempPath(255, TempVerzeichnis);
  GetTempFileName(TempVerzeichnis, 'TMP', 0, TempDateiName);

  // Antwort-Datei erzeugen
  AssignFile(Datei, TempDateiName);
  Rewrite(Datei);             // Antwort-Datei erzeugen und öffnen
  Writeln(Datei, #13#10);     // 1. Return ("Diskette einlegen ...")
  Writeln(Datei, #13#10);     // 2. Return (Diskettenbezeichnung)
  Writeln(Datei, 'n'#13#10);  // keine weitere Diskette
  CloseFile(Datei);           // Datei schließen

  // Befehlszeile zum Aufrufen von FORMAT.COM
  // command.com /c  = automatisch nach Beendigung schließen
  // format ...  /u  = unbedingt formatieren
  // format ...  /c  = defekte Sektoren prüfen
  Befehl := 'command.com /c format '+Laufwerk+' /u /c < '+TempDateiName;

  // StartupInfo initialisieren.
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);

  // DOS-Fenster soll nicht angezeigt werden.
  StartupInfo.dwFlags := StartF_UseShowWindow;
  StartupInfo.wShowWindow := SW_Hide;

  // Formatieren
  if CreateProcess(nil, PChar(Befehl), nil, nil,
                   False, 0, nil, 'c:\',
                   StartupInfo,
                   ProcessInfo) then begin
    // Warten bis Format beendet ist.
    WaitForSingleObject(ProcessInfo.hProcess, Infinite);
    CloseHandle(ProcessInfo.hProcess);
  end;

  // Antwort-Datei wieder löschen
  DeleteFile(TempDateiName);

  // War das Formatieren erfolgreich?
  if GetDiskFreeSpace(PChar(Laufwerk), SektorenProCluster,
                      BytesProSektor, FreieCluster, 
                      ClusterInsgesamt) then begin           
    // Anzahl defekter Sektoren berechnen
    Temp := FreieCluster * SektorenProCluster * BytesProSektor;
    Result := (1457664 - Temp) div BytesProSektor;
  end
  else              
    // Diskette nicht eingelegt oder unformatiert
    Result := - 1;
end;


Moderiert von user profile iconAya: Delphi-Tags hinzugefügt.
Moderiert von user profile iconTino: Quote-Tags hinzugefügt.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.08.03 12:58 
ausblenden volle Höhe Delphi-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:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
function Diskette_formatieren(Laufwerk: String): Integer; 
var Befehl : String; 
    Datei : TextFile; 
    TempDateiName : Array [0..255] of Char; 
    TempVerzeichnis : Array [0..255] of Char; 
    StartupInfo : TStartupInfo; 
    ProcessInfo : TProcessInformation; 
    SektorenProCluster : Integer; 
    BytesProSektor : Integer; 
    FreieCluster : Integer; 
    ClusterInsgesamt : Integer; 
    Temp : Integer; 
begin 
  // Datei zum Beantworten der Abfragen von FORMAT.EXE im Temp-Verzeichnis anlegen. 
  GetTempPath(255, TempVerzeichnis); 
  GetTempFileName(TempVerzeichnis, 'TMP', 0, TempDateiName); 

  // Antwort-Datei erzeugen 
  AssignFile(Datei, TempDateiName); 
  Rewrite(Datei);             // Antwort-Datei erzeugen und öffnen 
  Writeln(Datei, #13#10);     // 1. Return ("Diskette einlegen ...") 
  Writeln(Datei, #13#10);     // 2. Return (Diskettenbezeichnung) 
  Writeln(Datei, 'n'#13#10);  // keine weitere Diskette 
  CloseFile(Datei);           // Datei schließen 

  // Befehlszeile zum Aufrufen von FORMAT.COM 
  // command.com /c  = automatisch nach Beendigung schließen 
  // format ...  /u  = unbedingt formatieren 
  // format ...  /c  = defekte Sektoren prüfen 
  Befehl := 'command.com /c format '+Laufwerk+' /u /c < '+TempDateiName; 

  // StartupInfo initialisieren. 
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0); 
  StartupInfo.cb := SizeOf(TStartupInfo); 

  // DOS-Fenster soll nicht angezeigt werden. 
  StartupInfo.dwFlags := StartF_UseShowWindow; 
  StartupInfo.wShowWindow := SW_Hide; 

  // Formatieren 
  if CreateProcess(nil, PChar(Befehl), nil, nil, 
                   False, 0, nil, 'c:\', 
                   StartupInfo, 
                   ProcessInfo) then begin 
    // Warten bis Format beendet ist. 
    WaitForSingleObject(ProcessInfo.hProcess, Infinite); 
    CloseHandle(ProcessInfo.hProcess); 
  end; 

  // Antwort-Datei wieder löschen 
  DeleteFile(TempDateiName); 

  // War das Formatieren erfolgreich? 
  if GetDiskFreeSpace(PChar(Laufwerk), SektorenProCluster, 
                      BytesProSektor, FreieCluster,  
                      ClusterInsgesamt) then begin            
    // Anzahl defekter Sektoren berechnen 
    Temp := FreieCluster * SektorenProCluster * BytesProSektor; 
    Result := (1457664 - Temp) div BytesProSektor; 
  end 
  else               
    // Diskette nicht eingelegt oder unformatiert 
    Result := - 1; 
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Diskette_formatieren('a');
end;

[/delphi]
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.08.03 13:35 
a) Da hätte man drauf kommen können, was ... :oops:

b) Die Idee ist aber z.B. bei mir problematisch, weil ich Programme wie "format" oder "debug" umbenannt bzw. von der Platte entfernt habe. Eben, damit nicht einer mal ´ne stille Formatierung macht ... :)
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.08.03 13:52 
Man könnte vorher kucken, ob die Datei vorhanden ist.
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Fr 22.08.03 13:58 
Danke. :) Klappt ohne Fehler, komme aber nicht zu dem gewünschten Ergebnis. An was kann das liegen, wüsstet ihr etwas?

EDIT: also ohne Fehler meine ich, dass sich der Code ohne Probleme ausführen lässt.

EDIT 2: Ja, die Datei ist vorhanden.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 22.08.03 14:06 
chris_davidi hat folgendes geschrieben:
Danke. :) Klappt ohne Fehler, komme aber nicht zu dem gewünschten Ergebnis. An was kann das liegen, wüsstet ihr etwas?

Du müßtest eventuell da im Code, das ändern, dann noch das ergänzen und den Aufruf so anpassen. Dann sollte es gehen.
chris_davidi Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 76

Windows 98 SE
Delphi 3
BeitragVerfasst: Fr 22.08.03 14:08 
Jetzt klappt es, bei dem Aufruf des Buttons:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  Diskette_formatieren('a'); 
end;


Bei a fehlt der Doppelpunkt. Mehr nicht, sonst geht alles. Bin davon ausgegangen, dass es gestimmt hat.

Vielen Dank für eure Hilfe. :) Ist echt total nett. :)

Richtig also so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject); 
begin 
  Diskette_formatieren('a:'); 
end;


Gruss
Chris