![]() |
USB Stick sicher entfernen unter Vista
Hallöchen.
Was unter XP tadellos funktionierte das streikt nun unter Vista. Ich möchte aus meinem Programm heraus auch unter Vista einen Usb-Stick sicher entfernen. Hierzu habe ich auch alle Laufwerke in einer Listbox inkl. Instanz als Object basieren auf irgendnem Code den ich mal irgendwo gefunden habe. Bem.nicht schön aber funktionier ;-)
Delphi-Quellcode:
Den restlichen Programmcode hab ich mal hier gepostet
function TaForm.SaveRemoveDrive(Drive: Char): Boolean;
var S: string; idx, it, I: Integer; Inst: DEVINST; SymbolicName: string; VetoType: PNP_VETO_TYPE; //VetoBuffer: array [0..MAX_PATH-1] of TCHAR; begin Result := False; idx := -1; // update the list of drive mount points FillInRemovableDriveMountPoints(DriveMountPoints); // show the list of drive letters from the drive mount point list DriveList.Items.BeginUpdate; DriveList.Items.Clear; S := 'A:'; for I := 0 to DriveMountPoints.Count - 1 do begin S[1] := Char(DriveMountPoints.Objects[I]); GetDriveInstanceID(DriveMountPoints[I], Inst); SymbolicName := GetSymbolicName(Inst); it := DriveList.Items.AddObject(S + ' ' + ExtractSerialNumber(SymbolicName), TObject(Inst)); if UpperCase(S[1]) = UpperCase(Drive) then begin idx := it; end; end; DriveList.Items.EndUpdate; if idx > -1 then // find the mount point name for the drive letter clicked for I := 0 to DriveMountPoints.Count - 1 do begin if Char(DriveMountPoints.Objects[I]) = DriveList.Items[idx][1] then begin VetoType := 0; // try to do a silent safe removal // for drives not able to do a safe removal the function simply fails // FillChar(VetoBuffer[0], SizeOf(VetoBuffer), 0); // CM_Request_Device_Eject(DEVINST(DriveList.Items.Objects[I]), // @VetoType, @VetoBuffer[0], Length(VetoBuffer), 0); // do a safe removal with dialog CM_Request_Device_Eject(DEVINST(DriveList.Items.Objects[idx]), @VetoType, nil, 0, 0); Result := True; end; end; end;
Delphi-Quellcode:
Da dies nicht unter Vista funktioniert, bzw. einfach gar nichts tut hab ich recherchiert und nur bei MS gefunden das unter Vista man die Privilegien haben muss, also hab ichs noch damit versucht den CM_Request_Device_Eject wie folgt abzuändern:
uses
JwaWinBase, JwaWinType, Cfg, CfgMgr32, SetupApi, mySysUtils; {$R *.dfm} // encapsulate GetVolumeNameForVolumeMountPoint in a Delphi-style function function GetVolumeNameForVolumeMountPointString(Name: string): string; var Volume: array [0..MAX_PATH] of Char; begin FillChar(Volume[0], SizeOf(Volume), 0); GetVolumeNameForVolumeMountPoint(PChar(Name), @Volume[0], SizeOf(Volume)); Result := Volume; end; // fills the TStringList with the mount points of all removable drives procedure FillInRemovableDriveMountPoints(MountPoints: TStrings); const MAX_DRIVES = 26; var I: Integer; dwDriveMask: DWORD; DriveName: string; begin MountPoints.Clear; // get all mounted drive letters as bitmask dwDriveMask := GetLogicalDrives; DriveName := 'A:\'; // check all drive letters for I := 0 to MAX_DRIVES - 1 do // if drive letter exists if (dwDriveMask and (1 shl I)) <> 0 then begin DriveName[1] := 'A'; Inc(DriveName[1], I); // see if it is a removable drive if GetDriveType(PChar(DriveName)) = DRIVE_REMOVABLE then // store mount point string and corresponding drive letter in list MountPoints.AddObject(GetVolumeNameForVolumeMountPointString(DriveName), TObject(DriveName[1])); end; end; // Delphi style encapsulation for CM_Get_Device_ID function GetDeviceID(Inst: DEVINST): string; var Buffer: PTSTR; Size: ULONG; begin CM_Get_Device_ID_Size(Size, Inst, 0); // Required! See DDK help for CM_Get_Device_ID Inc(Size); Buffer := AllocMem(Size * SizeOf(TCHAR)); CM_Get_Device_ID(Inst, Buffer, Size, 0); Result := Buffer; FreeMem(Buffer); end; // simple extraction of the bus name from DeviceID string function ExtractBus(DeviceID: string): string; begin Result := Copy(DeviceID, 1, Pos('\', DeviceID) - 1); end; // get the "SymbolicName" registry entry of a device // for an USB device this string contains VID, PID and SerialNumber string function GetSymbolicName(Inst: DEVINST): string; var Len: DWORD; Key: HKEY; // a hopefully sufficiently large buffer Buffer: array [0..4095] of Char; begin CM_Open_DevNode_Key(Inst, KEY_READ, 0, REGDISPOSITION(RegDisposition_OpenExisting), Key, 0); Buffer[0] := #0; if Key <> INVALID_HANDLE_VALUE then begin Len := SizeOf(Buffer); RegQueryValueEx(Key, 'SymbolicName', nil, nil, @Buffer[0], @Len); RegCloseKey(Key); end; Result := Buffer; end; // extract a 4 digit hex number from SymbolicName // example "\??\USB#Vid_08ec&Pid_0010#0918121014000B59#{a5dcbf10-6530-11d2-901f-00c04fb951ed}" function ExtractNum(const SymbolicName, Prefix: string): Integer; var S: string; N: Integer; begin S := LowerCase(SymbolicName); N := Pos(Prefix, S); if N > 0 then begin S := '$' + Copy(SymbolicName, N + Length(Prefix), 4); Result := StrToInt(S); end else Result := 0; end; function ExtractVID(const SymbolicName: string): Integer; begin Result := ExtractNum(SymbolicName, 'vid_'); end; function ExtractPID(const SymbolicName: string): Integer; begin Result := ExtractNum(SymbolicName, 'pid_'); end; function ExtractSerialNumber(SymbolicName: string): string; var N: Integer; begin N := Pos('#', SymbolicName); if N >= 0 then begin SymbolicName := Copy(SymbolicName, N + 1, Length(SymbolicName)); N := Pos('#', SymbolicName); if N >= 0 then begin SymbolicName := Copy(SymbolicName, N + 1, Length(SymbolicName)); N := Pos('#', SymbolicName); if N >= 0 then Result := Copy(SymbolicName, 1, N - 1) else Result := ''; end; end else Result := ''; end; // find the "bus" DeviceID for a given mount point function GetDriveInstanceID(MountPointName: string; var DeviceInst: DEVINST): Boolean; const GUID_DEVINTERFACE_VOLUME: TGUID = '{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}'; var StorageGUID: TGUID; PnPHandle: HDEVINFO; DevData: TSPDevInfoData; DeviceInterfaceData: TSPDeviceInterfaceData; FunctionClassDeviceData: PSPDeviceInterfaceDetailData; Success: LongBool; Devn: Integer; BytesReturned: DWORD; Inst: DEVINST; S, FileName, MountName, DevID: string; begin Result := False; DeviceInst := 0; // enumerate all volumes StorageGUID := GUID_DEVINTERFACE_VOLUME; PnPHandle := SetupDiGetClassDevs(@StorageGUID, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE); if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then Exit; Devn := 0; repeat DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData); Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, StorageGUID, Devn, DeviceInterfaceData); if Success then begin DevData.cbSize := SizeOf(DevData); BytesReturned := 0; SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData); if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin FunctionClassDeviceData := AllocMem(BytesReturned); try FunctionClassDeviceData.cbSize := SizeOf(TSPDeviceInterfaceDetailData); if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then begin FileName := PTSTR(@FunctionClassDeviceData.DevicePath[0]); // get the grandparent DevNode which is the "bus" device // like "USB". This is the DevNode for CM_Request_Device_Eject and // several other useful operations Inst := DevData.DevInst; CM_Get_Parent(Inst, Inst, 0); CM_Get_Parent(Inst, Inst, 0); DevID := GetDeviceID(Inst); // no need in this example to check for USB only // if ExtractBus(DevID) = 'USB' then begin S := '\'; S := PTSTR(@FunctionClassDeviceData.DevicePath) + S; MountName := GetVolumeNameForVolumeMountPointString(S); if MountName = MountPointName then begin DeviceInst := Inst; Result := True; Exit; end; end; end; finally FreeMem(FunctionClassDeviceData); end; end; end; Inc(Devn); until not Success; SetupDiDestroyDeviceInfoList(PnPHandle); end; //============================================================================ procedure TaForm.FormCreate(Sender: TObject); var i : Integer; begin // never forget to load the dynamically linked APIs LoadSetupApi; LoadConfigManagerApi; DriveMountPoints := TStringList.Create; DriveMountPoints.Sorted := True; // initialize drive list if ParamCount > 0 then begin for i := 1 to ParamCount do begin if (Pos('DRIVEREMOVE:', UpperCase(ParamStr(i))) > 0) and (ParamStr(i)[length(ParamStr(i))] in ['A'..'Z','a'..'z']) then begin if not SaveRemoveDrive(ParamStr(i)[length(ParamStr(i))]) then begin end; end; end; end; PostMessage(Handle, WM_CLOSE, 0, 0); end; procedure TaForm.FormDestroy(Sender: TObject); begin DriveMountPoints.Free; UnloadConfigManagerApi; UnloadSetupApi; end;
Delphi-Quellcode:
Die SetPrivilege Funktion hier:
SetPrivilege('SeUndockPrivilege', true);
CM_Request_Device_Eject(DEVINST(DriveList.Items.Objects[idx]), @VetoType, nil, 0, CM_REMOVE_NO_RESTART); SetPrivilege('SeUndockPrivilege', False);
Delphi-Quellcode:
Funktioniert nicht, wer kann hier auf die Sprünge helfen nachdem ich alle gefundenen Quellen schon nach Lösungen durchforstet habe.
function SetPrivilege(privilegeName: string; enable: boolean): boolean;
var tpPrev, tp : TTokenPrivileges; token : THandle; dwRetLen : DWord; begin result := False; OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, token); tp.PrivilegeCount := 1; if LookupPrivilegeValue(nil, pchar(privilegeName), tp.Privileges[0].LUID) then begin if enable then tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED else tp.Privileges[0].Attributes := 0; dwRetLen := 0; result := AdjustTokenPrivileges(token, False, tp, SizeOf(tpPrev), tpPrev, dwRetLen); end; CloseHandle(token); end; |
Re: USB Stick sicher entfernen unter Vista
Wie denn, keiner hier irgendeine Idee :(
|
Re: USB Stick sicher entfernen unter Vista
Schade, ich denke kann dann diese Frage als unbeantwortet schließen :-(
|
Re: USB Stick sicher entfernen unter Vista
Hallo!
Kann es evtl. damit zusammenhängen, dass du unter Vista für einige Operationen höhere Rechte benötigst? Funktioniert denn dein Code, wenn du das Programm als Administrator startest? Dust Signs |
Re: USB Stick sicher entfernen unter Vista
Soweit ich weiß, ist es unter Vista nicht mehr notwendig dieses "sichere Entfernen" zu verwenden.
|
Re: USB Stick sicher entfernen unter Vista
Zitat:
|
Re: USB Stick sicher entfernen unter Vista
das ist nur dann nicht nötig wenn man den Cache deaktiviert. Als Standard ist der Cache deaktiviert und dann kann man den Stick einfach abziehen sonst nicht. Unter *nix muss man den Stick auch erst unmounten, sonst sind die Daten noch im Cache und nicht auf dem Stick
|
Re: USB Stick sicher entfernen unter Vista
Zitat:
Bin schon fast soweit mich direkt an dem TrayIcon und dem dahinter liegendem Popupmenü zum sicheren entfernen zu vergreifen :-D Zitat:
|
Re: USB Stick sicher entfernen unter Vista
Sieht so aus, dass Du ein Parent/Child-Beziehung zwischen Volume und Disk voraussetzt.
Das war schon unter XP nur für Wechseldatenträger und CDROMs ok, unter Vista nur noch für CDROMs. Hier habe ich in C++ gezeigt, wie es geht: ![]() Gruß Uwe |
Re: USB Stick sicher entfernen unter Vista
Hallöchen.
Was unter XP tadellos funktionierte das streikt nun unter Vista. Ich möchte aus meinem Programm heraus auch unter Vista einen Usb-Stick sicher entfernen. Hierzu habe ich auch alle Laufwerke in einer Listbox inkl. Instanz als Object basieren auf irgendnem Code den ich mal irgendwo gefunden habe. Bem.nicht schön aber funktionier Wink |
Re: USB Stick sicher entfernen unter Vista
Probier mal Folgendes:
Delphi-Quellcode:
Aufruf mit z.B. EjectVolume('J');
function OpenVolume(ADrive: char): THandle;
var RootName, VolumeName: string; AccessFlags: DWORD; DriveType:Cardinal; begin RootName := ADrive + ':\'; DriveType := GetDriveType(PChar(RootName)); case DriveType of DRIVE_REMOVABLE: AccessFlags := GENERIC_READ or GENERIC_WRITE; DRIVE_CDROM: AccessFlags := GENERIC_READ; // DRIVE_FIXED: // AccessFlags := GENERIC_READ or GENERIC_WRITE; else Result := INVALID_HANDLE_VALUE; exit; end; VolumeName := Format('\\.\%s:', [ADrive]); Result := CreateFile(PChar(VolumeName), AccessFlags, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if Result = INVALID_HANDLE_VALUE then RaiseLastWin32Error; end; function LockVolume(AVolumeHandle: THandle): boolean; const LOCK_TIMEOUT = 10 * 1000; // 10 Seconds LOCK_RETRIES = 20; LOCK_SLEEP = LOCK_TIMEOUT div LOCK_RETRIES; FSCTL_LOCK_VOLUME = (9 shl 16) or (0 shl 14) or (6 shl 2) or 0; var Retries: integer; BytesReturned: Cardinal; begin for Retries := 1 to LOCK_RETRIES do begin Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, nil, 0, nil, 0, BytesReturned, nil); if Result then break; Sleep(LOCK_SLEEP); end; end; function DismountVolume(AVolumeHandle: THandle): boolean; const FSCTL_DISMOUNT_VOLUME = (9 shl 16) or (0 shl 14) or (8 shl 2) or 0; var BytesReturned: Cardinal; begin Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, nil, 0, nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function PreventRemovalOfVolume(AVolumeHandle: THandle; APreventRemoval: boolean): boolean; const IOCTL_STORAGE_MEDIA_REMOVAL = ($2d shl 16) or (1 shl 14) or ($201 shl 2) or 0; type TPreventMediaRemoval = record PreventMediaRemoval: BOOL; end; var BytesReturned: Cardinal; PMRBuffer: TPreventMediaRemoval; begin PMRBuffer.PreventMediaRemoval := APreventRemoval; Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL, @PMRBuffer, SizeOf(TPreventMediaRemoval), nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function AutoEjectVolume(AVolumeHandle: THandle): boolean; const IOCTL_STORAGE_EJECT_MEDIA = ($2d shl 16) or (1 shl 14) or ($202 shl 2) or 0; var BytesReturned: Cardinal; begin Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, nil, 0, nil, 0, BytesReturned, nil); if not Result then RaiseLastWin32Error; end; function EjectVolume(ADrive: char): boolean; var VolumeHandle: THandle; begin Result := FALSE; // Open the volume VolumeHandle := OpenVolume(ADrive); if VolumeHandle = INVALID_HANDLE_VALUE then exit; try // Lock and dismount the volume if LockVolume(VolumeHandle) and DismountVolume(VolumeHandle) then begin // Set prevent removal to false and eject the volume if PreventRemovalOfVolume(VolumeHandle, FALSE) then AutoEjectVolume(VolumeHandle); end; finally // Close the volume so other processes can use the dr CloseHandle(VolumeHandle); end; end; |
Re: USB Stick sicher entfernen unter Vista
Vielen Dank für Ihre Antworten.
|
Re: USB Stick sicher entfernen unter Vista
Wie bekomme ich 'angeschlossenen USB-Info "(Geräte-Instanz-ID, Fahrerairbag, Schlüsselnamen ..) aus der Registry in Vista oder Windows 7 mit Delphi?
Wo ist diese Information in Windows Registry? Ich habe einen Code es funktioniert unter XP, aber nicht in Vista. Warum wird der Code funktioniert nicht auf Vista? Ich bin Stack wirklich darüber. Bitte helfen Sie. |
Re: USB Stick sicher entfernen unter Vista
Hallo TurboMartin,
unter Win 7 und als Admin geht es, unter Vista nicht. Keine Meldung, nix. Gruß |
Re: USB Stick sicher entfernen unter Vista
Zitat:
|
Re: USB Stick sicher entfernen unter Vista
Für Vista und Win7:
GetDriveInstanceID () except alles korrekt funktioniert. So GetDriveInstanceID(DriveMountPoints[I], Inst) returned from 'Inst' ist falsch. Ergebnisse für den gleichen USB: ----------------XP-----------Win7 ----------------------------------- Inst--------2788----------3908 Key---------1924-----------0 Was hat sich in Vista Registry geändert? |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Nochmal: Die Funktion setzt eine Parent/Child-Beziehung zwischen Volume und Disk voraus. Das war schon unter XP nur für Wechseldatenträger und CDROMs ok, aber nicht für Festplatten. Ab Vista ist das nur noch für CDROMs und USB-Floppys der Fall, sonst ist der Volume-Manager im Spiel. Hier habe ich in C++ gezeigt, wie es geht: ![]() Gruß Uwe |
Re: USB Stick sicher entfernen unter Vista
Ich hänge mich hier mal an mit meinem Problem:
Ich nutze folgenden Quelltext:
Delphi-Quellcode:
Der USB-Stick wird ausgehängt, aber irgendwie scheint ShChangeNotify zu scheitern. Das Symbol in der Taskleiste bleibt erhalten, ebendso wird im Explorer noch das Laufwerk angezeigt. Wie sag ich Windows nun, dass ich den Stick ausgehängt habe?
Function EjectVolume(ADrive: char): Boolean;
Function OpenVolume(ADrive: char): THandle; Var RootName, VolumeName : String; AccessFlags : DWORD; DriveType : Cardinal; Begin RootName := ADrive + ':\'; DriveType := GetDriveType(pChar(RootName)); Case DriveType Of DRIVE_REMOVABLE: AccessFlags := GENERIC_READ Or GENERIC_WRITE; DRIVE_CDROM: AccessFlags := GENERIC_READ; // DRIVE_FIXED: // AccessFlags := GENERIC_READ or GENERIC_WRITE; Else Result := INVALID_HANDLE_VALUE; Exit; End; VolumeName := Format('\\.\%s:', [ADrive]); Result := CreateFile(pChar(VolumeName), AccessFlags, FILE_SHARE_READ Or FILE_SHARE_WRITE, Nil, OPEN_EXISTING, 0, 0); If Result = INVALID_HANDLE_VALUE Then RaiseLastWin32Error; End; Function LockVolume(AVolumeHandle: THandle): Boolean; Const LOCK_TIMEOUT = 10 * 1000; // 10 Seconds LOCK_RETRIES = 20; LOCK_SLEEP = LOCK_TIMEOUT Div LOCK_RETRIES; FSCTL_LOCK_VOLUME = (9 Shl 16) Or (0 Shl 14) Or (6 Shl 2) Or 0; Var Retries : Integer; BytesReturned : Cardinal; Begin For Retries := 1 To LOCK_RETRIES Do Begin Result := DeviceIoControl(AVolumeHandle, FSCTL_LOCK_VOLUME, Nil, 0, Nil, 0, BytesReturned, Nil); If Result Then Break; Sleep(LOCK_SLEEP); End; End; Function DismountVolume(AVolumeHandle: THandle): Boolean; Const FSCTL_DISMOUNT_VOLUME = (9 Shl 16) Or (0 Shl 14) Or (8 Shl 2) Or 0; Var BytesReturned : Cardinal; Begin Result := DeviceIoControl(AVolumeHandle, FSCTL_DISMOUNT_VOLUME, Nil, 0, Nil, 0, BytesReturned, Nil); If Not Result Then RaiseLastWin32Error; End; Function PreventRemovalOfVolume(AVolumeHandle: THandle; APreventRemoval: Boolean): Boolean; Const IOCTL_STORAGE_MEDIA_REMOVAL = ($2D Shl 16) Or (1 Shl 14) Or ($201 Shl 2) Or 0; Type TPreventMediaRemoval = Record PreventMediaRemoval: BOOL; End; Var BytesReturned : Cardinal; PMRBuffer : TPreventMediaRemoval; Begin PMRBuffer.PreventMediaRemoval := APreventRemoval; Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL, @PMRBuffer, SizeOf(TPreventMediaRemoval), Nil, 0, BytesReturned, Nil); If Not Result Then RaiseLastWin32Error; End; Function AutoEjectVolume(AVolumeHandle: THandle): Boolean; Const IOCTL_STORAGE_EJECT_MEDIA = ($2D Shl 16) Or (1 Shl 14) Or ($202 Shl 2) Or 0; Var BytesReturned : Cardinal; Begin Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_EJECT_MEDIA, Nil, 0, Nil, 0, BytesReturned, Nil); If Not Result Then RaiseLastWin32Error; End; Var VolumeHandle : THandle; str : String; Begin Result := False; // Open the volume VolumeHandle := OpenVolume(ADrive); If VolumeHandle = INVALID_HANDLE_VALUE Then Exit; Try // Lock and dismount the volume If LockVolume(VolumeHandle) And DismountVolume(VolumeHandle) Then Begin // Set prevent removal to false and eject the volume If PreventRemovalOfVolume(VolumeHandle, False) Then Result := AutoEjectVolume(VolumeHandle); End; Finally // Close the volume so other processes can use the dr CloseHandle(VolumeHandle); End; If Result Then Begin str := ADrive + '\'; ShChangeNotify( SHCNE_MEDIAREMOVED, SHCNF_PATH, pChar(str), Nil); End; End; Gruß Sascha |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Bei einem CD-Laufwerk ginge Schublade auf, mehr nicht. Bei einem Kartenleser könnte man die Karte entnehmen und wieder einlegen -> geht wieder. Einem USB-Stick kann man nach dem Auswerfen beruhigt abziehen, Wiederbeleben geht nur durch erneutes Anschließen. Gruß Uwe |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Ein IOCTL_STORAGE_LOAD_MEDIA nach IOCTL_STORAGE_EJECT_MEDIA scheint Windows (Unter Vista auf jeden Fall! unter XP geht's nicht!) ein erneutes Einstecken des Sticks vorzugaukeln. Ob das Entfernen "sicher" ist kann ich nicht beurteilen. Gruß K-H |
Re: USB Stick sicher entfernen unter Vista
Zitat:
Zitat:
unter Vista zurück bringt wußte ich nicht - interessant. Sicher ist das Entfernen wenn - wie im Quelltext gezeigt - vor dem EJECT ein erfolgreiches LOCK und DISMOUNT erfolgten. Sonst ist es nicht besser als den Datenträger einfach zu entnehmen oder den Stick abzuziehen. Gruß Uwe |
Re: USB Stick sicher entfernen unter Vista
Danke für die Antworten!
|
Re: USB Stick sicher entfernen unter Vista
Für alle, die mal das gleiche Problem haben. Ich hab noch ne Möglichkeit gefunden, das Laufwerk aus dem Explorer zu entfernen.
Nachdem der Stick korrekt ausgeworfen wurde kann man folgendes aufrufen:
Delphi-Quellcode:
oder
DefineDosDevice(DDD_REMOVE_DEFINITION Or DDD_RAW_TARGET_PATH, pChar(String(ADrive + ':')), Nil);
Delphi-Quellcode:
Allerdings braucht man Adminrechte!
DefineDosDevice(DDD_EXACT_MATCH_ON_REMOVE Or DDD_REMOVE_DEFINITION Or DDD_RAW_TARGET_PATH, pChar(String(ADrive + ':')), pchar(DriveName);
Gruß BBB |
AW: USB Stick sicher entfernen unter Vista
Genau das gleiche Problem hatte ich auch :)
Ich frage mich nur gerade, ob das auch irgendwie ohne Adminrechte geht. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:45 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz