Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => Delphi => Konuyu başlatan: z - 06 Kasım 2014, 01:41:46

Başlık: Windowsun dosya yazma isini agirdan almasi
Gönderen: z - 06 Kasım 2014, 01:41:46
Delphide gelistirdigim bir program SD karta bir dosya yaziyor ve ekranda "Islem Tamam" mesaji veriyor.

Bende bu mesaji gorunce SD karti cikartiyorum. Biraz sonra windows gecikmeli yazma islemi var erken cikarttiniz gibi hata veriyor. Halbuki en az 1 sn beklemisim.

Neyse;

Delphi program Islem Tamam mesaji vermeden once dosyanin gercekten yazilip yazilmadigini test etsin ardindan islem tamam mesaji versin istiyorum.

Nasil bir cozum gerekiyor?

(OS: XP)

Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: mir_as82 - 06 Kasım 2014, 03:43:11
Hocam az buçuk C bilgim var. Buna galiba flush işlemi deniyor. Eğer delphinin flush işlemi tamamlandi mi tamamlanmadi mi diye windows un api lerini kullanip size geri döndürecek bir araci varsa onu deneyebilirsiniz.
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: M.Salim GÜLLÜCE - 06 Kasım 2014, 03:52:05
Aygıtı çıkar seçeneğini denersen garanti olur.
Aygıt meşgul cevabını alırsın.
meşguliyet bittiğinde zaten aygıtı ayırmış olursun.
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: t2 - 06 Kasım 2014, 08:12:38
format türünü değiştirmek işe yarayabilir. Fat,FaT32,ntfs,exFAT
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: diot - 06 Kasım 2014, 09:30:52
Aygıt yöneticisinde , disk sürücülerin altındaki disk sürücünüzü bulup , sağ tuş özellikler ve ardından ilkeler e tıklayıp. önbelleğe yazma ilkesindeki , aygıta yazma önbelleğini (cache) kapatın. Bu durumda uygulamanız direkt diske yazmaya başlayacaktır. Umarım bu şekilde sorununuz çözülür.
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: z - 06 Kasım 2014, 09:31:03
Format turunu degistiremem. (Zormat bana ozel)

mesaj birleştirme:: 06 Kasım 2014, 09:32:34

@Diot

Bu islemi programa nasil yaptiririm?

Cunku program her hangi bir kisiye verilecek. O kisiden bu tur islemler yapmasini istemem.
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: diot - 06 Kasım 2014, 09:34:37
registry den ilgili anahtarı değiştirmeniz lazım ama hangi anahtar bunu şu an bilmiyorum.


mesaj birleştirme:: 06 Kasım 2014, 09:42:44

HKLM\System\CurrentControlSet\Enum\IDE\<yourDiskName>\<serial no>\Device
Parameters\Disk\UserWriteCacheSetting = 0x0

0x0 = disable and 0x00000001 = enabled. It is a REG_DWORD.

olması lazım bir kontrol et istersen
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: mir_as82 - 06 Kasım 2014, 12:07:34
Hocam son yazdığın bilgiyi yazıp yazmadığını kontrol etsen? Yani sonuçta ramden sd karta yazıyorsun. SD kartta dosyanın sonuna gitsen ve file pointerini okusan. Sonuçta sd karta yazacağın verilerin senin ram in de ve sen onları dosyaya yazıyorsun. File pointer ve veri karşılaştırması sorunu çözer mi acaba?
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: z - 17 Kasım 2014, 13:00:10
Registryde degisiklik yapmadim. Buna her makine yetki vermeyebilir.

Sorunum hala devam ediyor.

64 K uzunlugunda dosya SD karta yazildi mesaji verdigimde SD kartta 64 K dosyami goruyorum.

65536. kayita git dedigimde gidiyor da.

Isletim sisteminde debug ile icine girip geziyorum her sey ok.

Fakat SD karti sokmeye kalktigimda gecikmeli yazma islemi hatasi aliyorum.

Isin kotusu bu hata SD kartin MBR unda check disk yapilmali bitinin set olmasina neden oluyor bu da uygulamamda hataya neden oluyor.


Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: mir_as82 - 17 Kasım 2014, 13:24:55
Hocam işletim sistemi ile kullandığınız dll arasında bir iletişimsizlikten kaynaklı olabilir mi. Yani yazdıktan sonra yapılması gerekli bir close işlemi vb.. Kullandığınız dll in manueline bakmak gerekiyordur belki.
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: diot - 17 Kasım 2014, 14:06:08
Yukarıdada belirtmiştim. HDD cache aktif iken bu sorunlar devam edecektir. 2. bir yöntemden bahsedeyim. windows'a usb porta bağlı cihazı güvenli kaldırma istegi yollayın.
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: z - 17 Kasım 2014, 14:59:16
DLL falan kullanmiyorum. SD kart isletim sistemi tarafindan depolama elemani olarak goruluyor zaten.

Dosyayi klasik fileopen filewrite komutlari olusturuyorum.

Isletim sisteminde tanimlamalara mudahale etmek istemiyorum. Bu benim isimi gorur ama yazdigim programi musterilerime donanim ile birlikte verecegim ve bu programi gunluk kullanacaklari PC'ye yukleyecekler.

Adamlara registryde ayarlamalari soyle soyle yapin diyemem. Desem de bazi makineler admin passwordu ile korunuyor. En nefret ettigim is, adminle muhatap olmak.

Bu yuzden @Diot bu cozume sicak bakmiyorum.

Benim istedigim su;

Programim yazma islemini yaptiktan sonra isterse 1dk beklesin onemli değil. Yeterki SD karti alabilirsiniz dediginde gecikmeli yazma hatasi ile karsilasmayayim.

Mevcut durumda dosyayi SD kartta olusturuyor ve dosyayi kapatiyorum. Okuma amacli aciyor ve dosya sonunda seek ediyorum. Baktim hatasiz seek de ediyor ediyor SD kartta dosyaniz hazir diye kullaniciya mesaj veriyorum.

Mesaji gorunce SD karti yuvasindan cikartiyorum biraz sonra windows kucuk bir pencerede gecikmeli yazma isleminde hata oldu diyor.

-----------

Eger eject etme isini yazilima yaptirabilirsem sorun kalkacak zira program SD karta dosyaniz hazir dediginde isletim sisteminde mouse ile SD karti eject et dersem bu sorun olusmuyor.

Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: MC_Skywalker - 17 Kasım 2014, 16:09:43
sisteminizdeki Antivirus programı da SD kartı bırakmıyor olabilir.  Antivurslerdeki On Access scan kısmı harici medyanın takılıp/takılmadığını ve Dosya okuma/yazma işlemini kontrol ediyor. Ve normalde windowsun işi bitmişken Antivirus programı yüzünde bekleme yapmanız gerekiyor.

Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: diot - 17 Kasım 2014, 16:42:21
Bu durumda NT kernelindeki dosya yazma ve okuma fonksiyonlarını kullanmayıp ASM biliyorsanız . Bios dan destekli INT13H ve DOS çekirdek destekli INT21H kullanarak yazma ve okuma rutinlerini kendiniz yazacaksınız. Şu an aklıma başka bir çözümde gelmiyor. Fakat sd kartı bios altından göreceği konusunda şüphelerim var.


Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: MC_Skywalker - 17 Kasım 2014, 17:12:13
SD kartı yeni nesil kartlarda görebilir zira butür medyalarda boot eyme seçenği var bazı bioslarda
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: bocek - 17 Kasım 2014, 17:38:13
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 (http://www.codeproject.com/Articles/13530/Eject-USB-disks-using-C)

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

ve bingo:
http://www.experts-exchange.com/Programming/Languages/Pascal/Delphi/Q_24811252.html (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 (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;
Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: z - 25 Kasım 2014, 06:19:09
@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.



Başlık: Ynt: Windowsun dosya yazma isini agirdan almasi
Gönderen: bocek - 25 Kasım 2014, 10:02:19
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.