System.ArgumentOutOfRangeException при развертывании программы - PullRequest
2 голосов
/ 18 января 2012

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

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)

Если я проверяю свой код: для строки 70

РЕДАКТИРОВАТЬ: эта функция будет вызываться / получать сообщения операционной системы 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

РЕДАКТИРОВАТЬ: эта функция проверяет _alreadyConnectedVolumes.Devices, который заполняется, когда программа запускается с volumeDeviceClass.Devices, когда вызывается LoadDownloadItems().Чтобы проверить и выбрать только что добавленное устройство.После этого проверьте, является ли это USB-устройством с функцией IsUsb.

РЕДАКТИРОВАТЬ: в _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);
        }
    }

РЕДАКТИРОВАТЬ: Некоторая дополнительная информация снова проверила мою программу на двух отдельных ноутбуках.Ноутбуки имеют одинаковые ресурсы (одна и та же операционная система (Windows 7 с пакетом обновления 1), оба HP EliteBook 8530p, ...), вот результаты:

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

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

  • C: \ -> жесткий диск
  • D: \ -> DVD-rw-station

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

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

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

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

  • C: \ -> жесткий диск (раздел 1 = основной)
  • D: \ -> жесткий диск (раздел 2)
  • E: \ -> DVD-rw-station

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

  • C: \ -> жесткий диск (раздел1 = основной)
  • D: \ -> жесткий диск (раздел 2)
  • E: \ -> DVD-rw-station
  • G: \ ->мой USB-накопитель

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

РЕДАКТИРОВАТЬ: (решено?) это решило мою проблему, думаю, я должен проверить это завтра, если оно точно работает.Но сейчас это решило проблемы вложенных циклов:

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-устройстве одновременно.

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

Ответы [ 2 ]

1 голос
/ 19 января 2012

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

0 голосов
/ 18 января 2012

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

if (volumeDeviceClass.Devices[position].IsUsb)

на это

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

Редактировать : также убедитесь, что _lstPictures содержит три записи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...