2012-01-18 2 views
2

На данный момент я работаю над программой, которая может обнаружить USB-устройство при подключении. Скопируйте все файлы и каталоги этого устройства в указанную папку. Все это работает. Я создаю эту программу, без проблем. Когда я запускаю .exe на своем ноутбуке Windows 7 (с одним разделом), программа выполняет то, что она должна делать. Когда я испытываю ту же программу на другой Windows 7 ноутбук (с двумя перегородками) и VISTA ноутбук Windows (с двумя перегородками) я получаю сообщение об ошибке (на голландском):System.ArgumentOutOfRangeException при развертывании программы

System.ArgumentOutOfRangeException: De index valt buiten het bereik. Deze mag niet negatief zijn en moet kleiner zijn dan de grootte van de verzameling. 
Parameternaam: index 
    bij System.ThrowHelper.ThrowArgumentOutOfRangeException() 
    bij System.Collections.Generic.List`1.get_Item(Int32 index) 
    bij PHL___USB_tool.USBTool.LoadDownloadItems() in C:\Users\2930682\Desktop\ONDERZOEK CopyFormatUSB\MyProgram\PHL - USB tool\PHL - USB tool\USB tool.cs:regel 162 
    bij PHL___USB_tool.USBTool.WndProc(Message& m) in C:\Users\2930682\Desktop\ONDERZOEK CopyFormatUSB\MyProgram\PHL - USB tool\PHL - USB tool\USB tool.cs:regel 70 
    bij System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
    bij System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
    bij System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 

Если я просматриваю код для line 70

EDIT: Эта функция будет называться/получать сообщения операционной системы Windows 7.

protected override void WndProc(ref Message m) 
    { 
     if (m.Msg == Native.WM_DEVICECHANGE) 
     { 
      if (m.WParam.ToInt32() == Native.DBT_DEVICEARRIVAL) 
      { 
       if (!_blnLoading) 
       { 
        switch (tabControl1.SelectedIndex) 
        { 
         case 0: SetProgress(_lstPictures); 
           lblCopies.Visible = false; 
           LoadDownloadItems(); 
           break; 
         case 1: SetProgress(_lstPictures2); 
           LoadUploadItems(); 
           break; 
         case 2: SetProgress(_lstPictures3); 
           LoadDeleteItems(); 
           break; 
        } 
       } 
      } 
      else if (m.WParam.ToInt32() == Native.DBT_DEVICEREMOVECOMPLETE) 
      { 
       _blnLoading = false; 

       _alreadyConnectedVolumes = null; 
       _alreadyConnectedVolumes = new VolumeDeviceClass(); 
      } 
     } 
     base.WndProc(ref m); 
    } 

и мой код строки 162

EDIT: перекрестные проверки этой функции _alreadyConnectedVolumes.Devices, которая заполняется, когда программа начинается с volumeDeviceClass.Devices когда LoadDownloadItems() называется. Чтобы проверить и выбрать новое добавленное устройство. После этого проверьте, является ли это USB-устройством с функцией IsUsb.

EDIT: в _lstPictures - это три Picturebox, которые помещаются туда, когда начинается программа.

private void LoadDownloadItems() 
    { 
     _blnLoading = true; 
     lblErrorDestination.Visible = false; 
     picErrorDestination.Visible = false; 
     _intFilesCopied = 0; 
     _intDirectoriesCopied = 0; 

     VolumeDeviceClass volumeDeviceClass = new VolumeDeviceClass(); 

     int position = -1; // need it for control, when to stop the for-loop 
     for (int i = 0; i < volumeDeviceClass.Devices.Count; i++) 
     { 
      if (position != -1) 
       break; 
      else 
      { 
       string logicalDrive = ((Volume)volumeDeviceClass.Devices[i]).LogicalDrive; 

       for (int j = 0; j < _alreadyConnectedVolumes.Devices.Count; j++) 
       { 
        if (((Volume)_alreadyConnectedVolumes.Devices[i]).LogicalDrive != logicalDrive) 
        { 
         position = i; 
         break; 
        } 
       } 
      } 
     } 

     // you don't need to check the position! 
     // cause every new device during run-time, will be a removable device or usb-device 
     if (position != -1 && volumeDeviceClass.Devices[position].IsUsb) 
     { 
      _connectedDevice = volumeDeviceClass.Devices[position]; 
      _strLogicalDrive = ((Volume) _connectedDevice).LogicalDrive; 

      _lstPictures[0].Image = Properties.Resources.Pass; 
      lblFirst.Text = "Usb-device (" + _strLogicalDrive + @"\) found"; 
      lblFirst.Refresh(); 
      RefreshProgress(_lstPictures); 

      if (_strDestination != null) 
      { 
       GetDirectories(_strLogicalDrive); 

       _lstPictures[1].Image = Properties.Resources.Pass; 
       _lstPictures[2].Image = Properties.Resources.Pass; 
       RefreshProgress(_lstPictures); 

       lblCopies.Visible = true; 
       lblCopies.Text = "Files copied: " + _intFilesCopied + "\tDirectories copied: " + _intDirectoriesCopied; 
      } 
      else 
      { 
       _lstPictures[1].Image = Properties.Resources.Error; 
       _lstPictures[2].Image = Properties.Resources.Error; 
       RefreshProgress(_lstPictures); 

       lblErrorDestination.Visible = true; 
       picErrorDestination.Visible = true; 
      } 

      UsbEject(); 

      _lstPictures[3].Image = Properties.Resources.Pass; 
      RefreshProgress(_lstPictures); 
     } 
    } 

EDIT: Некоторые дополнительные сведения проверены мою программу снова на двух отдельных ноутбуках. Ноутбуки имеют одни и те же ресурсы (та же операционная Sytem (Windows 7 Service Pack 1), как HP EliteBook 8530p, ...) это результаты:

Мой ноутбук (были программа работает отлично):

_alreadyConnectedVolumes.Devices существует из:

  • C: \ -> Harddisk
  • D: \ -> DVD-RW-станция

volumeDeviceClass.Devices существует из:

  • C: \ -> Harddisk
  • D: \ -> DVD-RW-станция
  • E: \ -> мой USB-диск -> это один был я могу делать действия без проблем!

ноутбук моего партнера (были я получаю ошибку, показанную в этой теме):

_alreadyConnectedVolumes.Devices существует из:

  • C: \ -> Жесткий диск (раздел 1 = первичный)
  • D: \ -> Жесткий диск (раздел 2)
  • E: \ -> DVD-RW-станция

volumeDeviceClass.Devices существует из:

  • C: \ -> жесткого диска (раздел 1 = первичные)
  • D: \ -> жесткого диска (раздела 2)
  • Е: \ -> DVD- RW-станция
  • G: \ -> мой USB-диск

В двух случаях, описанных здесь, я использовал тот же USB-устройство!

EDIT: (разрешено?) это решило мою проблему, я думаю, я должен проверить это завтра, если она точно работает. Но сейчас это решить проблемы вложенных циклов:

for (int i = 0; i < _alreadyConnectedVolumes.Devices.Count; i++) 
     { 

      string logicalDrive = ((Volume)_alreadyConnectedVolumes.Devices[i]).LogicalDrive; 

      for (int j = 0; j < volumeDeviceClass.Devices.Count; j++) 
      { 
       if (logicalDrive == ((Volume)volumeDeviceClass.Devices[j]).LogicalDrive) 
        volumeDeviceClass.Devices.RemoveAt(j); 
      } 
     } 

После этого я просто нужно, чтобы зачитать volumeDeviceClass.Devices были только один пункт в нем! Потому что мой прогрейм позволяет вам только регистрироваться на USB-устройстве одновременно.

Может ли кто-нибудь сказать мне, что является причиной ошибки. Причина не может думать об одном, но может быть ошибка?

+1

Можете ли вы проверить '_alreadyConnectedVolumes.Devices [i]' здесь количество устройств может быть меньше, чем 'i', вы можете проверить' i' и 'j',' i' не должно быть больше, чем 'j' –

+0

@AmarPalsapure Когда программы запускаются на моем ноутбуке '_alreadyConnectedVolumes.Devices [i]' содержит диск C: \, D: \ и E: \. Когда заполняется 'volumeDeviceClass.Devices', он содержит C: \, D: \, E: \ и диск F: \, последний из них - подключенный USB-накопитель newley, который я хочу использовать –

ответ

0

Это в основном догадка, но я думаю, что в некоторых случаях ваша переменная position не устанавливается. Попробуйте изменить это:

if (volumeDeviceClass.Devices[position].IsUsb) 

к этому

if (position != -1 && volumeDeviceClass.Devices[position].IsUsb) 

Edit: Кроме того, убедитесь, что _lstPictures имеет три записи в нем.

+1

Спасибо Matt за быстрый ответ ... Я попробую это и опубликую результаты. В _lstPictures всегда есть три recrods ... в Onload он заполняется. –

+0

Пробовал решение Мэтт предложил. Не работает, по-прежнему такая же ошибка. Проверено с помощью отладчика, '_lstPictures' заполняется и имеет в нем три PictureBox. Дополнительная информация: LoadDownloadItems() вызывается при подключении новых устройств. В '_alreadyConnectedVolumes' подключенные устройства и жесткие диски сохраняются при запуске программы. Поэтому, когда вызывается LoadDownloadItems(), я заполняю 'volumeDeviceClass.Devices'. Я перекрестно проверяю эти два, чтобы проверить, какое устройство новое, и после этого проверьте, является ли это USB-устройством. Другие идеи или решения могут решить эту проблему. Thanks Martijn –

+0

Какой тип 'Устройства'? –

1

В if (((Volume)_alreadyConnectedVolumes.Devices[i]).LogicalDrive != logicalDrive) вы используете i в качестве индекса вместо j!

+0

Да, также замеченный кем-то на msdn forum. Но это не решило проблему. Но, заметив эту проблему, я подумал, что э-э-э-э-э-э-э-э-э-э-э-э-э-э-э ... в общем-то ... попытаюсь исправить это, держать вас в курсе. –

+1

. Циклы for не сделали точно то, что они должны делать. Для ПК с только одним парированием это не проблема. Для нескольких разделов это дало ошибку, этот код исправил мою проблему в моем исходном вопросе! –

Смежные вопросы