【问题标题】:System.ArgumentOutOfRangeException when program is deployed部署程序时的 System.ArgumentOutOfRangeException
【发布时间】:2012-02-13 07:30:50
【问题描述】:

目前我正在开发一个可以在连接时检测 USB 设备的程序。将该设备的所有文件和目录复制到指定文件夹。所有这些都有效。我建立了这个程序,没有问题。当我在我的 Windows 7 笔记本电脑(带有一个分区)上运行 .exe 时,程序会执行它应该做的事情。当我在另一台 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 行代码

编辑:此函数交叉检查在调用LoadDownloadItems() 时以volumeDeviceClass.Devices 启动程序时填充的_alreadyConnectedVolumes.Devices。检查并选择新添加的设备。然后检查它是否是具有IsUsb功能的USB设备。

编辑:_lstPictures 中的三个图片框在程序启动时放入其中。

 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 Service Pack 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:\ --> 我的 U 盘

在此处描述的两种情况下,我使用了相同的 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 设备上注册。

谁能告诉我是什么导致了错误。因为想不出一个,但也许是一个错误?

【问题讨论】:

  • 你能检查_alreadyConnectedVolumes.Devices[i]这里的设备数量可能小于i,你可以检查iji不应该大于j
  • @AmarPalsapure 当程序在我的笔记本电脑上启动时,_alreadyConnectedVolumes.Devices[i] 包含 C:\、D:\ 和 E:\ 驱动器。当volumeDeviceClass.Devices 被填满时,它包含 C:\、D:\、E:\ 和 F:\ 驱动器,最后一个是我要使用的 newley 连接的 USB 驱动器

标签: c# windows visual-studio-2010


【解决方案1】:

if (((Volume)_alreadyConnectedVolumes.Devices[i]).LogicalDrive != logicalDrive) 中,您使用i 作为索引而不是j

【讨论】:

  • 是的,msdn 论坛上也有人注意到。但没有解决问题。但是通过注意到这个问题,我认为我的 for 循环总体上是有问题的......试图解决这个问题,让你们都发布
  • for 循环并没有完全按照他们应该做的那样做。对于只有一个分区的电脑来说,这不是问题。对于多个分区,它给出了错误,此代码修复了我的问题在我原来的问题中!
【解决方案2】:

这主要是一个猜测,但我认为在某些情况下,您的 position 变量没有被设置。尝试改变这个:

if (volumeDeviceClass.Devices[position].IsUsb)

到这里

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

编辑:还要确保_lstPictures 中包含三个记录。

【讨论】:

  • 感谢马特的快速回复...我会尝试并发布结果。 _lstPictures 中总是有三个记录...在 Onload 中它被填充了。
  • 尝试了马特建议的解决方案。没用,还是一样的错误。用调试器检查,_lstPictures 被填满,里面有三个 PictureBox。更多信息:当插入新设备时调用 LoadDownloadItems()。在_alreadyConnectedVolumes 中,连接的设备和硬盘在程序启动时存储。因此,当调用 LoadDownloadItems() 时,我填写 volumeDeviceClass.Devices。我交叉检查这两个,检查哪个设备是新的,然后检查它是否是 USB 设备。欢迎其他想法或解决方案来解决这个问题。谢谢马丁
  • Devices的类型是什么?
  • Devices 是一种返回 List&lt;Device&gt; 的方法,Device 类包含有关 USB 设备或硬盘(如 naam、logicaldrive 等)的信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多