Konuyu Oyla:
  • Derecelendirme: 4/5 - 1 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Wmi kullanırken hata vermesi.
#11
Şu adreste bazı şeyler yazıyor. Benim iki üstteki mesajımda belirttiğim gibi durumun SendMessage API'si ile ilgili olduğu hususunda.


Alıntı:See the beginning of chapter 13 in the OLE 2 Programmer's Reference Volume 1 for the categories of OLE calls. An understanding of these categories is required for this article.

The majority of OLE calls are synchronous calls. A synchronous call to a different process yields to that process and waits for a reply from that process. In addition, OLE has input-synchronized calls that relate to the inplace-activation interfaces. Input-synchronized calls are implemented using an inter-process/inter-thread SendMessage.


Bu bir senkron çağrı olduğu için, mesajı gönderen bloke olmuş durumda ve muhtemelen bilgisini verdiği device'ı da lock'lamış durumdadır. OnArrival olayının bir başka thread içinden çağrılıp işin yine ana thread'e devredilmesi sayesinde, mesajı gönderen gönderdiği mesajın yanıtını hızla almış ve device ile ilgili işleri de tamamlamış olur.

Denemedim ama okuduklarımdan anladığım kadarı ile gelen mesajın içinde COM objelerini kullanıyor olmak hataya neden olmuyor. Hataya neden olan, gelen mesajın senkron olması ve hızlıca gönderene dönemiyor olması. Daha gelen mesaj sonuçlanmamış iken, mesajın konusu olan device ile ilgili bir iş yapılmaya çalışılması bu problemin nedeni gibi görünüyor.

Yine denemedim ama, muhtemelen; bir uygulama WM_DEVICECHANGE olay yöneticisi içinde uzun bir bekleme kodu koysa; bir başka uygulama üzerinden de WMI ile ya da başka bir şekilde o cihaza ulaşılmaya kalkılsa aynı hata yeniden alınır gibi geliyor bana.

Tabii çok büyük ihtimalle, mesajı gönderen taraf (yani işletim sistemi) aptal olmadığı için , muhtemelen mesajı SendMessage ile değil; SendMessageTimeOut ile göndermiştir. Smile
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#12
Hocam yolun daha çok başındayım.25 yaşındayım.Öğreneceğim tonla bilgi var, bunun farkındayım. Genellikle sizler sayesinde çok fazla ilerleme kaydettim.Hepinize çok teşekkür ederim.
Cevapla
#13
(20-02-2019, Saat: 12:05)seci20 Adlı Kullanıcıdan Alıntı: Hocam yolun daha çok başındayım.25 yaşındayım.Öğreneceğim tonla bilgi var, bunun farkındayım. Genellikle sizler sayesinde çok fazla ilerleme kaydettim.Hepinize çok teşekkür ederim.

Kendi adıma rica ederim. Öğrenmek isteyene kapımız açık. Siz yeterki, merakınızı, ilginizi, sabrınızı kaybetmeyin. Gerisi zamanla kendiliğinden gelecektir. Ama öğrenmek için fırsatları kaçırmamak gerekir. Misal, bu konu başlığı altında belirtilen SendMessage, SendMessageTimeOut, senkron mesaj gönderme, asenkron mesaj gönderme gibi konuları merak edip denemelisiniz. Bu merak sizde mevcut ise kimse ilerlemenize engel olamaz.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#14
(20-02-2019, Saat: 12:02)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Şu adreste bazı şeyler yazıyor. Benim iki üstteki mesajımda belirttiğim gibi durumun SendMessage API'si ile ilgili olduğu hususunda.


Alıntı:See the beginning of chapter 13 in the OLE 2 Programmer's Reference Volume 1 for the categories of OLE calls. An understanding of these categories is required for this article.

The majority of OLE calls are synchronous calls. A synchronous call to a different process yields to that process and waits for a reply from that process. In addition, OLE has input-synchronized calls that relate to the inplace-activation interfaces. Input-synchronized calls are implemented using an inter-process/inter-thread SendMessage.


Bu bir senkron çağrı olduğu için, mesajı gönderen bloke olmuş durumda ve muhtemelen bilgisini verdiği device'ı da lock'lamış durumdadır. OnArrival olayının bir başka thread içinden çağrılıp işin yine ana thread'e devredilmesi sayesinde, mesajı gönderen gönderdiği mesajın yanıtını hızla almış ve device ile ilgili işleri de tamamlamış olur.

Denemedim ama okuduklarımdan anladığım kadarı ile gelen mesajın içinde COM objelerini kullanıyor olmak hataya neden olmuyor. Hataya neden olan, gelen mesajın senkron olması ve hızlıca gönderene dönemiyor olması. Daha gelen mesaj sonuçlanmamış iken, mesajın konusu olan device ile ilgili bir iş yapılmaya çalışılması bu problemin nedeni gibi görünüyor.

Yine denemedim ama, muhtemelen; bir uygulama WM_DEVICECHANGE olay yöneticisi içinde uzun bir bekleme kodu koysa; bir başka uygulama üzerinden de WMI ile ya da başka bir şekilde o cihaza ulaşılmaya kalkılsa aynı hata yeniden alınır gibi geliyor bana.

Tabii çok büyük ihtimalle, mesajı gönderen taraf (yani işletim sistemi) aptal olmadığı için , muhtemelen mesajı SendMessage ile değil; SendMessageTimeOut ile göndermiştir. Smile



Örnek olarak şöyle bir şey yaptım:
Usb takıldığında tetiklenen OnArrival olayına şunları yazdım;
procedure TfrmDummy.USBDetector1Arrival(Sender: TObject; Drive: String);
begin
 CoInitialize(nil);
 try
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
 finally
   CoUninitialize;
 end;
end

Aynı hatayı aldım.
Yukarıdaki durumda USB ile yeniden iletişim kurma vs. yok.

Ayrıca olay içine sadece 30 sn bekletme koysam bir sorun olmuyor. (işletim sistemi yazanlar Tuğrul Bey kadar düşünceli değiller galiba  Wink )
There's no place like 127.0.0.1
WWW
Cevapla
#15
(20-02-2019, Saat: 14:04)SimaWB Adlı Kullanıcıdan Alıntı:
(20-02-2019, Saat: 12:02)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: Şu adreste bazı şeyler yazıyor. Benim iki üstteki mesajımda belirttiğim gibi durumun SendMessage API'si ile ilgili olduğu hususunda.




Bu bir senkron çağrı olduğu için, mesajı gönderen bloke olmuş durumda ve muhtemelen bilgisini verdiği device'ı da lock'lamış durumdadır. OnArrival olayının bir başka thread içinden çağrılıp işin yine ana thread'e devredilmesi sayesinde, mesajı gönderen gönderdiği mesajın yanıtını hızla almış ve device ile ilgili işleri de tamamlamış olur.

Denemedim ama okuduklarımdan anladığım kadarı ile gelen mesajın içinde COM objelerini kullanıyor olmak hataya neden olmuyor. Hataya neden olan, gelen mesajın senkron olması ve hızlıca gönderene dönemiyor olması. Daha gelen mesaj sonuçlanmamış iken, mesajın konusu olan device ile ilgili bir iş yapılmaya çalışılması bu problemin nedeni gibi görünüyor.

Yine denemedim ama, muhtemelen; bir uygulama WM_DEVICECHANGE olay yöneticisi içinde uzun bir bekleme kodu koysa; bir başka uygulama üzerinden de WMI ile ya da başka bir şekilde o cihaza ulaşılmaya kalkılsa aynı hata yeniden alınır gibi geliyor bana.

Tabii çok büyük ihtimalle, mesajı gönderen taraf (yani işletim sistemi) aptal olmadığı için , muhtemelen mesajı SendMessage ile değil; SendMessageTimeOut ile göndermiştir. Smile



Örnek olarak şöyle bir şey yaptım:
Usb takıldığında tetiklenen OnArrival olayına şunları yazdım;
procedure TfrmDummy.USBDetector1Arrival(Sender: TObject; Drive: String);
begin
 CoInitialize(nil);
 try
    FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
    FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
 finally
   CoUninitialize;
 end;
end

Aynı hatayı aldım.
Yukarıdaki durumda USB ile yeniden iletişim kurma vs. yok.

Ayrıca olay içine sadece 30 sn bekletme koysam bir sorun olmuyor. (işletim sistemi yazanlar Tuğrul Bey kadar düşünceli değiller galiba  Wink )

Denediğiniz ve bizimle paylaştığınız için teşekkürler. Sadece CoInitialize/CoUnInitialize kullanımı da aynı hataya neden oluyor mu ? Bir de denemişken, CoInitialize'yi COINIT_MULTITHREADED parametresi ile dener misiniz ? Ayrıca, Sleep(30000) koyduktan sonra, bilgisi verilen cihaza bir başka uygulama üzerinden erişim sağlayabiliyor musunuz ?

İşletim sistemi yazanlar benden kat be kat bilgilidirler elbette. Benimki okuduklarımdan elde etmiş olduğum çıkarımlardı sadece.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#16
  • Sadece CoInitialize/CoUnInitialize kullandığımda sorun yok.
  • Sleep esnasında Usb Flash Diskte dosya oluşturup silebiliyorum.
  • COINIT_MULTITHREADED ile değişen bir şey olmadı.
There's no place like 127.0.0.1
WWW
Cevapla
#17
(20-02-2019, Saat: 16:18)SimaWB Adlı Kullanıcıdan Alıntı:
  • Sadece CoInitialize/CoUnInitialize kullandığımda sorun yok.
  • Sleep esnasında Usb Flash Diskte dosya oluşturup silebiliyorum.
  • COINIT_MULTITHREADED ile değişen bir şey olmadı.

Teşekkür ederim, testler ve paylaşım için. Buradan benim anladığım; hatanın CoInitialize/CoUnInitialize çağrımından değil, WMI erişiminden kaynaklandığı söylenebilir. Sleep esnasında aslında Windows altından değil, bir başka uygulamadan yine WMI ile o cihazı sorgulayabiliyor musunuz diye sormaya çalışmıştım.

Tekrar sağolun.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#18
Ben şimdi eve geldim ve merakımdan kolları sıvadım. Gelen mesajı yeniden mesaj sırasına atıp oradan dönünce bekleme zamanındaki değişkenliği bertaraf etmiş olduk.

Minareden at beni, in aşağıya tut beni bir çözüm oldu. Wink

Denemek bedava...
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    const
      WM_BenimMesaj = WM_USER + 401;
    procedure OnBenimUSBMessage(var Msg: TMessage); message WM_BenimMesaj;
    procedure FUSBDetectorOnArrival(Sender: TObject; Drive: String);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses USBDetect, ActiveX, ComObj;

Var
  FUSBDetector : TUSBDetector;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FUSBDetector := TUSBDetector.Create(nil);
  FUSBDetector.OnArrival := FUSBDetectorOnArrival;
end;

procedure TForm1.FUSBDetectorOnArrival(Sender: TObject; Drive: String);
begin
  // Minareden at beni, in aşağıya tut beni.
  PostMessage(self.Handle, WM_BenimMesaj, 0, 0); // Topu Taca Atıyoruz...
end;

procedure TForm1.OnBenimUSBMessage(var Msg: TMessage);
Const
  WbemComputer  = 'localhost';
  WbemUser      = '';
  WbemPassword  = '';
Var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
begin
  CoInitialize(nil);
  try
     FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
     FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  finally
    CoUninitialize;
  end;
  ShowMessage( 'USB Takıldı...');
end;



ya da sizin kodlara göre değerlendirmek istediğinizde...

procedure TForm1.OnBenimUSBMessage(var Msg: TMessage);
var
 Y : string;
begin
 Y := GetWMIstring('','Win32_DiskDrive','SerialNumber');
 ShowMessage( 'USB Takıldı... S/N :' + Y );
end;
Saygılarımla
Muharrem ARMAN

guplouajuixjzfm15eqb.gif
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Rest Hata Yakalama m_ekici 9 1.458 08-03-2024, Saat: 19:30
Son Yorum: aegean
  Tanım Bulamadım Bu Hata İçin hi_selamlar 11 1.338 30-10-2023, Saat: 18:20
Son Yorum: hi_selamlar
  delphi de garip bir hata ercanskose 11 1.501 26-07-2023, Saat: 12:00
Son Yorum: delphiman
  UniDBGridColumnFilter Release Modda Hata veriyor yhackup 18 2.542 19-01-2023, Saat: 10:29
Son Yorum: yhackup
  CmdExecMode->amAsync Transaction Hata YILDIRIMBEY 1 532 24-10-2022, Saat: 00:07
Son Yorum: 3ddark



Konuyu Okuyanlar: 1 Ziyaretçi