Einzelnen Beitrag anzeigen

Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.622 Beiträge
 
Delphi 12 Athens
 
#1

USB-Laufwerk formatieren

  Alt 13. Jun 2017, 09:56
Ich möchte Daten auf einen USB-Datenträger kopieren. Ist dieser vorher nicht leer, frage ich nach, ob er formatiert werden soll. Dazu benutze ich SHFormatDrive. Das funktioniert auch im Prinzip, allerdings habe ich während meiner Tests gelegentlich das Phänomen, dass nach dem UAC-Dialog die Caption meines Formulars (dessen Handle ich an SHFormatDrive übergebe) geändert und SHFMT_ERROR zurückgegeben wird. Leider ist das nicht reproduzierbar, könnte das daran liegen, dass ich in einer VM aus einem Mac entwickle und das USB-Durchschleifen nicht immer zu 100% klappt? Mich macht insbesondere stutzig, dass die Funktion meine Caption anfasst. Achja, hier mein Code (von SO kopiert und etwas angepasst):
Delphi-Quellcode:
const
  SHFMT_DRV_A = 0;
  SHFMT_DRV_B = 1;
  SHFMT_ID_DEFAULT = $FFFF;
  SHFMT_OPT_QUICKFORMAT = 0;
  SHFMT_OPT_FULLFORMAT = 1;
  SHFMT_OPT_SYSONLY = 2;
  SHFMT_ERROR = -1;
  SHFMT_CANCEL = -2;
  SHFMT_NOFORMAT = -3;

function SHFormatDrive(
  hWnd: hWnd;
  Drive: UINT;
  fmtID: UINT;
  Options: UINT
  ): DWORD; stdcall; external 'Shell32.dll';

procedure TfrmWizard.FormatDrive(const ADrive: string);
var
  FmtRes: Longint;
  cCharTemp: Char;
  nDrive: UINT;
begin
  if (ADrive = '') or not DirectoryExists(ADrive) then
    Exit;
  cCharTemp := AnsiUpperCase(ADrive)[1];
  if GetDriveType(PChar(cCharTemp + ':\')) <> DRIVE_REMOVABLE then
    Exit;
  nDrive := Ord(cCharTemp) - Ord('A');
  try
    FmtRes := SHFormatDrive(Handle, nDrive, SHFMT_ID_DEFAULT,
      SHFMT_OPT_QUICKFORMAT);
    case FmtRes of
      SHFMT_ERROR:
        raise Exception.Create
          ('Während der Formatierung ist ein Fehler aufgetreten.');
      SHFMT_CANCEL:
        raise Exception.Create('Formatierung durch Benutzer abgebrochen.');
      SHFMT_NOFORMAT:
        raise Exception.Create('Der Datenträger kann nicht formatiert werden.');
    end;
    ...
  except
    on E: Exception do
      begin
        ...
        MessageBox(0, PChar(E.Message), 'Fehler', MB_OK or MB_ICONERROR);
      end;
  end;
end;
[edit] Ein 2. Aufruf funktioniert bislang immer, ich habe den Eindruck, das könnte evtl. an den Energiesparoptionen liegen. [/edit]
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen

Geändert von DeddyH (13. Jun 2017 um 09:58 Uhr)
  Mit Zitat antworten Zitat