Windowsun dosya yazma isini agirdan almasi

Başlatan z, 06 Kasım 2014, 01:41:46

bocek

#15
Alıntı yapılan: z - 17 Kasım 2014, 14:59:16
Eger eject etme isini yazilima yaptirabilirsem sorun kalkacak ..

şurda C# için:
http://www.codeproject.com/Articles/13530/Eject-USB-disks-using-C

şurda C++ için:
http://support.microsoft.com/kb/165721

ve bingo:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_24811252.html

burda da var:
http://stackoverflow.com/questions/434688/how-can-i-remove-a-usb-flash-disk-programmatically-using-delphi

şuraya da kopyalayalım kaybolur maybolur:
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;
 
// #define FSCTL_LOCK_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 6, METHOD_BUFFERED, FILE_ANY_ACCESS)
  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
// #define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
  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
// #define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
  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;
  Pmerhabauffer: TPreventMediaRemoval;
begin
  Pmerhabauffer.PreventMediaRemoval := APreventRemoval;
  Result := DeviceIoControl(AVolumeHandle, IOCTL_STORAGE_MEDIA_REMOVAL,
    @Pmerhabauffer, SizeOf(TPreventMediaRemoval), nil, 0, BytesReturned, nil);
  if not Result then
    RaiseLastWin32Error;
end;
 
function AutoEjectVolume(AVolumeHandle: THandle): boolean;
const
// #define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
  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;
1 ya da 0. işte 'bit'ün mesele..

z

@Bocek

Denedikten sonra cevap yazmayi unutmusum. Sorunumu bu yazilim eklentisi cozdu. Tesekkurler.

Cozum beraberinde kucuk bir sorunu getirdi ama ilki kadar dert degil. Dosya karta yazildiktan sonra eject yapilinca isletim sistemi, gecikmeli yazma islemine oncelik verip yazma isini derhal bitiriyor ardindan SD karti sistem surucu listesinden siliyor.

Kullanici bu asamada bir sey yapmayi unuttugunu farkediyor ve programi tekrar calistiriyor. Ancak SD kart fiziksel olarak takili oldugu halde soft eject isleminden dolayi sistemde SD kart yok gorunuyor. Tek cozumu SD karti sokup tekrar takmak.

Ama hic dert etmiyorum artik.



Bana e^st de diyebilirsiniz.   www.cncdesigner.com

bocek

Hocam işinizin görülmesine sevindim. Bahsettiğiniz problemden verdiğim linklerde de bahsediliyordu  ama bu aslında br problem olarak görülmemeli. Nasıl ki mesela sisteme harici bir hd taktık, işimizi gördük bitirdik ve remove vs. diyerek bağlantısını kopardık. Sonra bir dosya kopyalamayı unuttuğumuzu gördük tekrar diske erişmeye çalıştığımızda ne yapmamız gerekiyor? Çıkarıp takmamız.
Sizinki de aynı aslında ve bunun başka bir yolu yok.
1 ya da 0. işte 'bit'ün mesele..