Я не знаю, как вы могли бы сделать это без программирования, но я написал приложения, которые делают именно то, что вы хотите. Вот как это реализовать.
Когда в систему добавляется новое устройство (например, USB-накопитель), Windows отправляет сообщение WM_DEVICECHANGE
всем окнам приложений верхнего уровня. Событие, которое нужно искать, это DBT_DEVICEARRIVAL
(которое указывается через wParam
этого сообщения).
lParam
сообщения должен сначала рассматриваться как DEV_BROADCAST_HDR
. Заголовок будет указывать (через член dbch_devicetype
), является ли устройство фактически томом (DBT_DEVTYP_VOLUME
). Если это том, вы можете интерпретировать lParam
исходного сообщения как DEV_BROADCAST_VOLUME
. Затем эта структура будет указывать назначенные буквы дисков через член dbcv_unitmask
.
Чтобы сделать это (надеюсь) немного более понятным, вот некоторый рабочий код из моей реализации на C #:
private static void MessageEventsMessageReceived( object sender, MessageReceivedEventArgs e ) {
// Check if this is a notification regarding a new device.);
if( e.Message.WParam == (IntPtr)NativeMethods.DBT_DEVICEARRIVAL ) {
Log.Info( "New device has arrived" );
// Retrieve the device broadcast header
NativeMethods.DEV_BROADCAST_HDR deviceBroadcastHeader =
(NativeMethods.DEV_BROADCAST_HDR)
Marshal.PtrToStructure( e.Message.LParam, typeof( NativeMethods.DEV_BROADCAST_HDR ) );
if( (int)NativeMethods.DBT_DEVTYP.DBT_DEVTYP_VOLUME == deviceBroadcastHeader.dbch_devicetype ) {
Log.Info( "Device type is a volume (good)." );
NativeMethods.DEV_BROADCAST_VOLUME volumeBroadcast =
(NativeMethods.DEV_BROADCAST_VOLUME)
Marshal.PtrToStructure( e.Message.LParam, typeof( NativeMethods.DEV_BROADCAST_VOLUME ) );
Log.InfoFormat( "Unit masked for new device is: {0}", volumeBroadcast.dbcv_unitmask );
int driveIndex = 1;
int bitCount = 1;
while( bitCount <= 0x2000000 ) {
driveIndex++;
bitCount *= 2;
if( ( bitCount & volumeBroadcast.dbcv_unitmask ) != 0 ) {
Log.InfoFormat( "Drive index {0} is set in unit mask.", driveIndex );
Log.InfoFormat( "Device provides drive: {0}:", (char)( driveIndex + 64 ) );
int index = driveIndex;
char driveLetter = (char)( driveIndex + 64 );
// Do something with driveLetter
}
}
} else {
Log.InfoFormat( "Device type is {0} (ignored).", Enum.GetName( typeof( NativeMethods.DBT_DEVTYP ), deviceBroadcastHeader.dbch_devicetype ) );
}
}
}