PDA

View Full Version : usb disk drive insert/remove detection - real time



terrorhell
شنبه 11 بهمن 1393, 20:32 عصر
سلام
دوستان من میخوام وقتی usb flash به کامپیوتر وصل میشه همون لحظه شناسایی بشه و عملیاتی انجام بشه

یک تیکه کد از اینترنت پیدا کردم اما وقتی usb رو میکشم خوب عمل میکنه اما وقتی بهش usb رو وصل میکنم گاهی اوقات اصلا نمیتونه شناسایی کنه یا خیلی دیر شناسایی میشه و محتوای فلش یو اس بی باز میشه

ممنون میشم دوستان راهنمایی کنند

مرسی

Saman_12
شنبه 11 بهمن 1393, 20:38 عصر
قبلا اینکارو کرده بودم کافیه توی تایمر چک کنی الان تعداد usb ها چند تاست قبلا چند تا بوده (یه لیست خارج از تابع نیازه) اگر کم شده باشه یعنی خارج شده حالا دوتا لیست جدید و قدیمی رو مقایسه کن اونی که تو هر دو تا نیست حذف شده و مشابه برای اظافه شدن(System.IO.DriveInfo)

terrorhell
شنبه 11 بهمن 1393, 20:43 عصر
سامان عزیز امکانش هست نمونه کد بزاری ؟

Saman_12
شنبه 11 بهمن 1393, 21:13 عصر
این دیگه نمونه نداره :

private event DrivesChangedEventHandler DrivesChanged;
private delegate void DrivesChangedEventHandler(DriveInfo drinfo, string kind);
private DriveInfo[] drivelist = DriveInfo.GetDrives();


private void CheckDrives()
{
DriveInfo[] curdrivelist = DriveInfo.GetDrives();


if (!(drivelist.Length == curdrivelist.Length)) {
DriveInfo drive = null;


if (drivelist.Length > curdrivelist.Length) {


for (Int32 i = 0; i <= drivelist.Length - 1; i++) {


if (!curdrivelist.Contains(drivelist[i])) {
drive = drivelist[i];
break;
}
}


if (DrivesChanged != null) {
DrivesChanged(drive, "Remove");
}
Console.WriteLine(drive.Name + " Remove");
} else {


for (Int32 i = 0; i <= curdrivelist.Length - 1; i++) {


if (!drivelist.Contains(curdrivelist[i])) {
drive = curdrivelist[i];
break;
}
}


if (DrivesChanged != null) {
DrivesChanged(drive, "Insert");
}
Console.WriteLine(drive.Name + " Insert");
}
drivelist = curdrivelist;
}
}

terrorhell
شنبه 11 بهمن 1393, 21:45 عصر
مرسی لطف کردین

فقط اینکه اسم درایو را نمیشه از این نمونه کد شما بیرون کشید ؟ که مثلاً درایوی که وصل شده Z یا X یا .... چی هست

Saman_12
شنبه 11 بهمن 1393, 22:00 عصر
پس
drive.Name چیه؟

terrorhell
شنبه 11 بهمن 1393, 23:05 عصر
drive.name فقط مقدار C:/ را برمیگردونه

Saman_12
شنبه 11 بهمن 1393, 23:44 عصر
جالبه اینم از خارقالعاده های سی شارپه!
اصلاحش کردم بفرمایید :
private event DrivesChangedEventHandler DrivesChanged; private delegate void DrivesChangedEventHandler(DriveInfo drinfo, string kind);
private DriveInfo[] drivelist = DriveInfo.GetDrives();

private void CheckDrives()
{
DriveInfo[] curdrivelist = DriveInfo.GetDrives();


if (drivelist.Length != curdrivelist.Length)
{
DriveInfo drive = null;


if (drivelist.Length > curdrivelist.Length)
{


for (Int32 i = 0; i <= drivelist.Length - 1; i++)
{
bool isexist = false;
for (Int32 j=0; j <= curdrivelist.Length-1; j++)
{
if (drivelist[i].Name == curdrivelist[j].Name) {isexist = true; break;}
}

if (isexist == false) {drive = drivelist[i]; break;}
}


if (DrivesChanged != null)
{
DrivesChanged(drive, "Remove");
}
Console.WriteLine(drive.Name + " Remove");
}
else
{


for (Int32 i = 0; i <= curdrivelist.Length - 1; i++)
{
bool isexist = false;
for (Int32 j = 0; j <=drivelist.Length - 1; j++)
{
if (curdrivelist[i].Name == drivelist[j].Name) { isexist = true; break; }
}

if (isexist == false) { drive = curdrivelist[i]; break; }
}


if (DrivesChanged != null)
{
DrivesChanged(drive, "Insert");
}
Console.WriteLine(drive.Name + " Insert");
}


drivelist = curdrivelist;
}
}

terrorhell
شنبه 11 بهمن 1393, 23:48 عصر
متشکرم مرسی
فقط یه سوالی ، الان من این متد رو داخل تایمر گذاشتم و هر 1 ثانیه چک میکنم ، این کار فضای زیادی از cpu رو اشغال میکنه ! درسته ؟
راه حل دیکه ای واسه این قضیه دارین ؟

Saman_12
یک شنبه 12 بهمن 1393, 00:06 صبح
میتونی جای تایمر از این استفاده کنی :
const int WM_DEVICECHANGE = 0x0219;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_DEVICECHANGE) { CheckDrives(); }
}

اگر آنتی ویروس به کد قبلی گیر داد به این تغییرش بده :

private event DrivesChangedEventHandler DrivesChanged;
private delegate void DrivesChangedEventHandler(DriveInfo drinfo, string kind);
private DriveInfo[] drivelist = DriveInfo.GetDrives();

private void CheckDrives()
{
DriveInfo[] curdrivelist = DriveInfo.GetDrives();


if (drivelist.Length != curdrivelist.Length)
{
List<string> curnames = GetDrivesName(curdrivelist);
List<string> names = GetDrivesName(drivelist);
DriveInfo drive = null;


if (drivelist.Length > curdrivelist.Length)
{


for (Int32 i = 0; i <= names.Count - 1; i++)
{
if (!curnames.Contains(names[i])) {drive = drivelist[i]; break;}
}


if (DrivesChanged != null)
{
DrivesChanged(drive, "Remove");
}
Console.WriteLine(drive.Name + " Remove");
}
else
{


for (Int32 i = 0; i <= curnames.Count - 1; i++)
{


if (!names.Contains(curnames[i])) { drive = curdrivelist[i]; break; }
}


if (DrivesChanged != null)
{
DrivesChanged(drive, "Insert");
}
Console.WriteLine(drive.Name + " Insert");
}


drivelist = curdrivelist;
}
}


private List<string> GetDrivesName(DriveInfo[] drives)
{
List<string> result = new List<string>();
for (Int32 i = 0; i <= drives.Length - 1;i++ )
{
result.Add(drives[i].Name);
}
return result;
}

terrorhell
یک شنبه 12 بهمن 1393, 11:49 صبح
مرسی ممنون خیلی لطف کردین , این کد شما توانایی برگرداندن سریال نامبر سخت افزار فلش دیسک رو داره یا باید از توابع دیگری برای این کار استفاده کرد .

چون یک سریال توسط سیستم عامل به دیسک تعلق میگیره و یک سریال نامبر منحصر به فرد برای سخت افزار تعریف شده است .

Saman_12
یک شنبه 12 بهمن 1393, 12:45 عصر
نه نداره متاسفانه من هم اطلاعی در این زمینه ندارم.

terrorhell
یک شنبه 12 بهمن 1393, 13:13 عصر
نه نداره متاسفانه من هم اطلاعی در این زمینه ندارم.

مرسی

برای بار اول که برنامه باز میشه اگر فلش دیسک به کامپیوتر وصل باشه پیغامی مبنی بر وصل بودن فلش به کامپیوتر نمیده ، این قسمت رو چجوری باید حل کرد ؟

Saman_12
یک شنبه 12 بهمن 1393, 21:06 عصر
اصلا به کد دقت کردین؟
برای این کار باید جداگانه چک کنید (WM_DeviceChange وقتی فرستاده میشه که تغییری رخ داده باشه نه هر وقت برنامه شما اجرا شه).
بعدش هم تو Event ی که فراخوانی میشه حتما چک کنید که درایو Removeable باشه(یا تو ی همین تابع)