关于枚举COM接口的问题

来源:互联网 发布:php use关键字定义函数 编辑:程序博客网 时间:2024/05/24 06:41

去年我开发了一个软件,需要枚举COM接口,而我以前使用vb6时使用了API来完成。但现在使用VS2003,其并没有这方面的类。因此我还是使用API来完成。下面是代码:

using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace System.Shangfei.Controls.SerialPort
{
    
/// <summary>
    
/// EnumPort 的摘要说明。
    
/// </summary>

    public class EnumPort
    
{
        
public ArrayList Ports=new ArrayList();
        
        
"Dll定义"

        
public EnumPort()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
            ListPorts(null);
        }

        
public EnumPort(string Prx)
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
            ListPorts(Prx);
        }

        
public void  Dispose()
        
{
            Ports.Clear();
        }

                
        
/// <summary>
        
/// 搜索系统的端口,并放在Ports数组列表中
        
/// </summary>
        
/// <param name="Prx">过滤字符串</param>

        private void ListPorts(string Prx) 
        
{
            
int pcReturned = 0;
            
int pcbNeeded = 0;
            IntPtr outb 
= IntPtr.Zero;
            
            EnumPorts(
null1, outb, 0out pcbNeeded, out pcReturned);
            outb 
= Marshal.AllocHGlobal(pcbNeeded+1);
            EnumPorts(
null1, outb, pcbNeeded, out pcbNeeded, out pcReturned);
            PORT_INFO_1[] portsArray 
= new PORT_INFO_1[pcReturned];

            IntPtr current 
= outb;
            
for (int i=0; i<pcReturned; i++)
            
{
                portsArray[i] 
= (PORT_INFO_1)Marshal.PtrToStructure(current,typeof(PORT_INFO_1));
                current
=(IntPtr)((int)current+Marshal.SizeOf(typeof(PORT_INFO_1)));
                
if (Prx!=null)
                
{
                    
if (portsArray[i].pName.StartsWith(Prx.ToUpper() ))
                        Ports.Add(
new string(portsArray[i].pName.ToCharArray()));
                }

                
else
                
{Ports.Add(new string(portsArray[i].pName.ToCharArray()));}
            }

            
for (int i=0; i<Ports.Count ; i++)
            
{
                
if (Ports[i].ToString().EndsWith(":"))
                    Ports[i]
=Ports[i].ToString().Substring(0,Ports[i].ToString().Length-1);
            }

            Marshal.FreeHGlobal(outb);
                    
        }

    }
//class
    
}

在使用过程中也正常,没有发现问题。但是心里总有些不舒服,我不是很喜欢在C#环境中加入API。前段时间我使用Reflector查看了VS2005中SerialPort类,在其中有一个EnumPort类可以实现枚举COM接口。其使用访问注册表来实现此功能,我立即将其代码移到VS2003中,发现运行正常。终于去了我一块心病。

public string[] ListCOMPorts()
        
{
            RegistryKey localMachine 
= null;
            RegistryKey key2 
= null;
            
string[] strArray = null;
            
new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM").Assert();
            
try
            
{
                localMachine 
= Registry.LocalMachine;
                key2 
= localMachine.OpenSubKey(@"HARDWAREDEVICEMAPSERIALCOMM"false);
                
if (key2 != null)
                
{
                    
string[] valueNames = key2.GetValueNames();
                    strArray 
= new string[valueNames.Length];
                    
for (int i = 0; i < valueNames.Length; i++)
                    
{
                        strArray[i] 
= (string) key2.GetValue(valueNames[i]);
                    }

                }

            }

            
finally
            
{
                
if (localMachine != null)
                
{
                    localMachine.Close();
                }

                
if (key2 != null)
                
{
                    key2.Close();
                }

                CodeAccessPermission.RevertAssert();
            }

            
if (strArray == null)
            
{
                strArray 
= new string[0];
            }

            
return strArray;
        }

不过,此方式目前只实现了COM的枚举,没有LPT等接口的。而采用API方式可以枚举出所有接口。另外我在网上看到采用WMI(System.Management命名空间中)提供的功能实现COM的枚举,这个我不清楚它在Window 98环境下是否可以工作,我没有Window 98系统环境,不能测试,如果有那位朋友知道,方便的话可以告诉我。

 

原创粉丝点击