none
C#编写的ActiveX控件导致IE无响应有哪些原因呢? RRS feed

  • 问题

  • 我在vs2010 .net4的环境下开发一个ActiveX控件,分别在4部PC测试,3部PC可用,有1部PC一加载Activex控件iE就死了(ActiveX控件尚未加载)。

    这部问题pc安装了 .net4客户端环境+.net2环境,在这台PC上还有MFC开发的ActiveX(OCX)控件是没问题的。

    大家说说 都有哪些情况会引起这样的效果?

     

    PS:

    这个ActiveX控件启动后,将读取Windows USB设备列表,然后判断是否已经接入某种设备,如果没有接入的话,ActiveX控件将有MessageBox提示。


    Windows Mobile
    2011年8月27日 2:23

答案

  • 感谢大家热心支持,问题找到了。

     

    是控件自身问题导致的,

     

    上面的在样例程序中,//Skip这个地方处理出现了问题,由于问题PC有个USB驱动未正确安装,导致While死循环了。

     

     

    //Declare vars
       while (!Native.SetupDiGetDeviceRegistryProperty(hDevInfo,
             DeviceInfoData,
             Native.SPDRP_DEVICEDESC,
             0,
             DeviceName,
             Native.MAX_DEV_LEN,
             IntPtr.Zero))
       {
       //Skip
       }
       bool bMatch = true

     

     


    Windows Mobile
    2011年8月30日 9:46

全部回复

  • 操作系统版本,IE设置,帐号权限设置,杀毒软件等.
    2011年8月27日 4:24
  • 问题找到了,可能是由于或去设备列表时引起的问题。 获取设备列表我采用的是C#调用Windows API,客户机 Windows XP SP3

     

    比如:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    /*
     * HardwareHelperLib
     * ===========================================================
     * Windows XP SP2, VS2005 C#.NET, DotNet 2.0
     * HH Lib is a hardware helper for library for C#.
     * It can be used for notifications of hardware add/remove
     * events, retrieving a list of hardware currently connected,
     * and enabling or disabling devices.
     * ===========================================================
     * LOG:   Who?  When?    What?
     * (v)1.0.0 WJF   11/26/07  Original Implementation
     */
    namespace HardwareHelperLib
    {
      #region Unmanaged
    
      public class Native
      {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, DEV_BROADCAST_DEVICEINTERFACE NotificationFilter, UInt32 Flags);
    
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern uint UnregisterDeviceNotification(IntPtr hHandle);
    
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(ref Guid gClass, UInt32 iEnumerator, IntPtr hParent, UInt32 nFlags);
    
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern int SetupDiDestroyDeviceInfoList(IntPtr lpInfoSet);
    
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern bool SetupDiEnumDeviceInfo(IntPtr lpInfoSet, UInt32 dwIndex, SP_DEVINFO_DATA devInfoData);
    
        [DllImport("setupapi.dll", SetLastError = true)]
        public static extern bool SetupDiGetDeviceRegistryProperty(IntPtr lpInfoSet, SP_DEVINFO_DATA DeviceInfoData, UInt32 Property, UInt32 PropertyRegDataType, StringBuilder PropertyBuffer, UInt32 PropertyBufferSize, IntPtr RequiredSize);
    
        [DllImport("setupapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool SetupDiSetClassInstallParams(IntPtr DeviceInfoSet, IntPtr DeviceInfoData, IntPtr ClassInstallParams, int ClassInstallParamsSize);
    
        [DllImport("setupapi.dll", CharSet = CharSet.Auto)]
        public static extern Boolean SetupDiCallClassInstaller(UInt32 InstallFunction,IntPtr DeviceInfoSet, IntPtr DeviceInfoData);
        
        // Structure with information for RegisterDeviceNotification.
        [StructLayout(LayoutKind.Sequential)]
        public struct DEV_BROADCAST_HANDLE
        {
          public int dbch_size;
          public int dbch_devicetype;
          public int dbch_reserved;
          public IntPtr dbch_handle;
          public IntPtr dbch_hdevnotify;
          public Guid dbch_eventguid;
          public long dbch_nameoffset;
          public byte dbch_data;
          public byte dbch_data1;
        }
    
        // Struct for parameters of the WM_DEVICECHANGE message
        [StructLayout(LayoutKind.Sequential)]
        public class DEV_BROADCAST_DEVICEINTERFACE
        {
          public int dbcc_size;
          public int dbcc_devicetype;
          public int dbcc_reserved;
        }
    
        //SP_DEVINFO_DATA
        [StructLayout(LayoutKind.Sequential)]
        public class SP_DEVINFO_DATA
        {
          public int cbSize;
          public Guid classGuid;
          public int devInst;
          public ulong reserved;
        };
    
        [StructLayout(LayoutKind.Sequential)]
        public class SP_DEVINSTALL_PARAMS
        {
          public int cbSize;
          public int Flags;
          public int FlagsEx;
          public IntPtr hwndParent;
          public IntPtr InstallMsgHandler;
          public IntPtr InstallMsgHandlerContext;
          public IntPtr FileQueue;
          public IntPtr ClassInstallReserved;
          public int Reserved;
          [MarshalAs(UnmanagedType.LPTStr)] public string DriverPath;
        };
    
        [StructLayout(LayoutKind.Sequential)]
        public class SP_PROPCHANGE_PARAMS 
        {
          public SP_CLASSINSTALL_HEADER ClassInstallHeader=new SP_CLASSINSTALL_HEADER();
          public int StateChange;
          public int Scope;
          public int HwProfile;
        };
    
        [StructLayout(LayoutKind.Sequential)]
        public class SP_CLASSINSTALL_HEADER
        {
          public int cbSize;
          public int InstallFunction;
        }; 
    
        //PARMS
        public const int DIGCF_ALLCLASSES = (0x00000004);
        public const int DIGCF_PRESENT = (0x00000002);
        public const int INVALID_HANDLE_VALUE = -1;
        public const int SPDRP_DEVICEDESC = (0x00000000);
        public const int MAX_DEV_LEN = 1000;
        public const int DEVICE_NOTIFY_WINDOW_HANDLE = (0x00000000);
        public const int DEVICE_NOTIFY_SERVICE_HANDLE = (0x00000001);
        public const int DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = (0x00000004);
        public const int DBT_DEVTYP_DEVICEINTERFACE = (0x00000005);
        public const int DBT_DEVNODES_CHANGED = (0x0007);
        public const int WM_DEVICECHANGE = (0x0219);
        public const int DIF_PROPERTYCHANGE = (0x00000012);
        public const int DICS_FLAG_GLOBAL = (0x00000001);
        public const int DICS_FLAG_CONFIGSPECIFIC = (0x00000002);
        public const int DICS_ENABLE = (0x00000001);
        public const int DICS_DISABLE = (0x00000002);
      }
    
      #endregion
    
      public class HH_Lib
      {
        Version m_Version = new Version(1, 0, 0);
    
        #region Public Methods
    
        //Name:   GetAll
        //Inputs:  none
        //Outputs: string array
        //Errors:  This method may throw the following errors.
        //     Failed to enumerate device tree!
        //     Invalid handle!
        //Remarks: This is code I cobbled together from a number of newsgroup threads
        //     as well as some C++ stuff I translated off of MSDN. Seems to work.
        //     The idea is to come up with a list of devices, same as the device
        //     manager does. Currently it uses the actual "system" names for the
        //     hardware. It is also possible to use hardware IDs. See the docs
        //     for SetupDiGetDeviceRegistryProperty in the MS SDK for more details.
        public string[] GetAll()
        {
          List<string> HWList = new List<string>();
          try
          {
            Guid myGUID = System.Guid.Empty;
            IntPtr hDevInfo = Native.SetupDiGetClassDevs(ref myGUID, 0, IntPtr.Zero, Native.DIGCF_ALLCLASSES | Native.DIGCF_PRESENT);
            if (hDevInfo.ToInt32() == Native.INVALID_HANDLE_VALUE)
            {
              throw new Exception("Invalid Handle");
            }
            Native.SP_DEVINFO_DATA DeviceInfoData;
            DeviceInfoData = new Native.SP_DEVINFO_DATA();
            DeviceInfoData.cbSize = 28;
            //is devices exist for class
            DeviceInfoData.devInst = 0;
            DeviceInfoData.classGuid = System.Guid.Empty;
            DeviceInfoData.reserved = 0;
            UInt32 i;
            StringBuilder DeviceName = new StringBuilder("");
            DeviceName.Capacity = Native.MAX_DEV_LEN;
            for (i = 0; Native.SetupDiEnumDeviceInfo(hDevInfo, i, DeviceInfoData); i++)
            {
              //Declare vars
              while (!Native.SetupDiGetDeviceRegistryProperty(hDevInfo,
                                      DeviceInfoData,
                                      Native.SPDRP_DEVICEDESC,
                                      0,
                                      DeviceName,
                                      Native.MAX_DEV_LEN,
                                      IntPtr.Zero))
              {
                //Skip
              }
              HWList.Add(DeviceName.ToString());
            }
            Native.SetupDiDestroyDeviceInfoList(hDevInfo);
          }
          catch (Exception ex)
          {
            throw new Exception("Failed to enumerate device tree!",ex);
          }
          return HWList.ToArray();
        }
        //Name:   SetDeviceState
        //Inputs:  string[],bool
        //Outputs: bool
        //Errors:  This method may throw the following exceptions.
        //     Failed to enumerate device tree!
        //Remarks: This is nearly identical to the method above except it
        //     tries to match the hardware description against the criteria
        //     passed in. If a match is found, that device will the be
        //     enabled or disabled based on bEnable.
        public bool SetDeviceState(string[] match, bool bEnable)
        {
          try
          {
            Guid myGUID = System.Guid.Empty;
            IntPtr hDevInfo = Native.SetupDiGetClassDevs(ref myGUID, 0, IntPtr.Zero, Native.DIGCF_ALLCLASSES | Native.DIGCF_PRESENT);
            if (hDevInfo.ToInt32() == Native.INVALID_HANDLE_VALUE)
            {
              return false;
            }
            Native.SP_DEVINFO_DATA DeviceInfoData;
            DeviceInfoData = new Native.SP_DEVINFO_DATA();
            DeviceInfoData.cbSize = 28;
            //is devices exist for class
            DeviceInfoData.devInst = 0;
            DeviceInfoData.classGuid = System.Guid.Empty;
            DeviceInfoData.reserved = 0;
            UInt32 i;
            StringBuilder DeviceName = new StringBuilder("");
            DeviceName.Capacity = Native.MAX_DEV_LEN;
            for (i = 0; Native.SetupDiEnumDeviceInfo(hDevInfo, i, DeviceInfoData); i++)
            {
              //Declare vars
              while (!Native.SetupDiGetDeviceRegistryProperty(hDevInfo,
                                      DeviceInfoData,
                                      Native.SPDRP_DEVICEDESC,
                                      0,
                                      DeviceName,
                                      Native.MAX_DEV_LEN,
                                      IntPtr.Zero))
              {
                //Skip
              }
              bool bMatch = true;
              foreach (string search in match)
              {
                if (!DeviceName.ToString().ToLower().Contains(search.ToLower()))
                {
                  bMatch = false;
                  break;
                }
              }
              if (bMatch)
              {
                ChangeIt(hDevInfo, DeviceInfoData, bEnable);
              }
            }
            Native.SetupDiDestroyDeviceInfoList(hDevInfo);
          }
          catch (Exception ex)
          {
            throw new Exception("Failed to enumerate device tree!", ex);
            return false;
          }
          return true;
        }
        //Name:   HookHardwareNotifications
        //Inputs:  Handle to a window or service, 
        //     Boolean specifying true if the handle belongs to a window
        //Outputs: false if fail, otherwise true
        //Errors:  This method may log the following errors.
        //     NONE
        //Remarks: Allow a window or service to receive ALL hardware notifications.
        //     NOTE: I have yet to figure out how to make this work properly
        //     for a service written in C#, though it kicks butt in C++. At any
        //     rate, it works fine for windows forms in either.
        public bool HookHardwareNotifications(IntPtr callback, bool UseWindowHandle)
        {
          try
          {
            Native.DEV_BROADCAST_DEVICEINTERFACE dbdi = new Native.DEV_BROADCAST_DEVICEINTERFACE();
            dbdi.dbcc_size = Marshal.SizeOf(dbdi);
            dbdi.dbcc_reserved = 0;
            dbdi.dbcc_devicetype = Native.DBT_DEVTYP_DEVICEINTERFACE;
            if (UseWindowHandle)
            {
              Native.RegisterDeviceNotification(callback, 
                dbdi, 
                Native.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | 
                Native.DEVICE_NOTIFY_WINDOW_HANDLE);
            }
            else
            {
              Native.RegisterDeviceNotification(callback, 
                dbdi, 
                Native.DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | 
                Native.DEVICE_NOTIFY_SERVICE_HANDLE);
            }
            return true;
          }
          catch (Exception ex)
          {
            string err = ex.Message;
            return false;
          }
        }
        //Name:   CutLooseHardareNotifications
        //Inputs:  handle used when hooking
        //Outputs: None
        //Errors:  This method may log the following errors.
        //     NONE
        //Remarks: Cleans up unmanaged resources. 
        public void CutLooseHardwareNotifications(IntPtr callback)
        {
          try
          {
            Native.UnregisterDeviceNotification(callback);
          }
          catch
          {
            //Just being extra cautious since the code is unmanged
          }
        }
        #endregion
    
        #region Private Methods
    
        //Name:   ChangeIt
        //Inputs:  pointer to hdev, SP_DEV_INFO, bool
        //Outputs: bool
        //Errors:  This method may throw the following exceptions.
        //     Unable to change device state!
        //Remarks: Attempts to enable or disable a device driver. 
        //     IMPORTANT NOTE!!!  This code currently does not check the reboot flag.
        //     =================  Some devices require you reboot the OS for the change
        //               to take affect. If this describes your device, you 
        //               will need to look at the SDK call:
        //               SetupDiGetDeviceInstallParams. You can call it 
        //               directly after ChangeIt to see whether or not you need 
        //               to reboot the OS for you change to go into effect.
        private bool ChangeIt(IntPtr hDevInfo, Native.SP_DEVINFO_DATA devInfoData, bool bEnable)
        {
          try
          {
            //Marshalling vars
            int szOfPcp;
            IntPtr ptrToPcp;
            int szDevInfoData;
            IntPtr ptrToDevInfoData;
    
            Native.SP_PROPCHANGE_PARAMS pcp = new Native.SP_PROPCHANGE_PARAMS();
            if (bEnable)
            {
              pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Native.SP_CLASSINSTALL_HEADER));
              pcp.ClassInstallHeader.InstallFunction = Native.DIF_PROPERTYCHANGE;
              pcp.StateChange = Native.DICS_ENABLE;
              pcp.Scope = Native.DICS_FLAG_GLOBAL;
              pcp.HwProfile = 0;
              
              //Marshal the params
              szOfPcp = Marshal.SizeOf(pcp);
              ptrToPcp = Marshal.AllocHGlobal(szOfPcp);
              Marshal.StructureToPtr(pcp, ptrToPcp, true);
              szDevInfoData = Marshal.SizeOf(devInfoData);
              ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);
    
              if (Native.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(Native.SP_PROPCHANGE_PARAMS))))
              {
                Native.SetupDiCallClassInstaller(Native.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);
              }
              pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Native.SP_CLASSINSTALL_HEADER));
              pcp.ClassInstallHeader.InstallFunction = Native.DIF_PROPERTYCHANGE;
              pcp.StateChange = Native.DICS_ENABLE;
              pcp.Scope = Native.DICS_FLAG_CONFIGSPECIFIC;
              pcp.HwProfile = 0;
            }
            else
            {
              pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Native.SP_CLASSINSTALL_HEADER));
              pcp.ClassInstallHeader.InstallFunction = Native.DIF_PROPERTYCHANGE;
              pcp.StateChange = Native.DICS_DISABLE;
              pcp.Scope = Native.DICS_FLAG_CONFIGSPECIFIC;
              pcp.HwProfile = 0;
            }
            //Marshal the params
            szOfPcp = Marshal.SizeOf(pcp);
            ptrToPcp = Marshal.AllocHGlobal(szOfPcp);
            Marshal.StructureToPtr(pcp, ptrToPcp, true);
            szDevInfoData = Marshal.SizeOf(devInfoData);
            ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);
            Marshal.StructureToPtr(devInfoData, ptrToDevInfoData,true);
    
            bool rslt1 = Native.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(Native.SP_PROPCHANGE_PARAMS)));
            bool rstl2 = Native.SetupDiCallClassInstaller(Native.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);
            if ((!rslt1) || (!rstl2))
            {
              throw new Exception("Unable to change device state!");
              return false;
            }
            else
            {
              return true;
            }
          }
          catch (Exception ex)
          {
            return false;
          }
        }
    
        #endregion
      }
    }
    

     在部分XP PC上运行正常,但是仅仅有一部PC不好用,系统什么情况能引起“SetupAPI”,这样的函数不起作用?如:SetupDiGetDeviceRegistryProperty。

     

     


    Windows Mobile
    2011年8月29日 6:36
  • 既然代码能在其他电脑上正常运行,那就说明问题基本上不在代码上。

    建议:

    1. 重置IE 设置。

    2.杀毒软件(如果有,先关下试试,或者是其他软件也在使用SetupAPI

    3.拷贝一个SetupAPI。dll(正常运行的电脑)

    4.设置一下权限问题。(XP的好像不需要)

    希望有用。

     


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年8月30日 2:27
    版主
  • 感谢大家热心支持,问题找到了。

     

    是控件自身问题导致的,

     

    上面的在样例程序中,//Skip这个地方处理出现了问题,由于问题PC有个USB驱动未正确安装,导致While死循环了。

     

     

    //Declare vars
       while (!Native.SetupDiGetDeviceRegistryProperty(hDevInfo,
             DeviceInfoData,
             Native.SPDRP_DEVICEDESC,
             0,
             DeviceName,
             Native.MAX_DEV_LEN,
             IntPtr.Zero))
       {
       //Skip
       }
       bool bMatch = true

     

     


    Windows Mobile
    2011年8月30日 9:46
  • 很高兴您能找到问题所在并解决了问题。

     


    Best Regards,
    Rocky Yue[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年8月31日 3:20
    版主