C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表
/* ----------------------------------------------------------
文件名称:WMIUsbQuery.cs 作者:秦建辉 MSN:splashcn@msn.com
QQ:36748897 博客:http://blog.csdn.net/jhqin 开发环境:
Visual Studio V2010
.NET Framework 4 Client Profile 版本历史:
V1.3 2011年09月08日
代码优化 V1.2 2011年09月02日
增加基于服务的查询 V1.1 2011年09月01日
增加基于设备ID的查询,解决LIKE子句中反斜杠字符引发的WQL查询异常 V1.0 2011年08月30日
基于WMI实现对USB设备的查询
------------------------------------------------------------ */
using System;
using System.Management;
using System.Text.RegularExpressions;
using System.Collections.Generic; namespace Splash.IO.PORTS
{
/// <summary>
/// 即插即用设备信息结构
/// </summary>
public struct PnPEntityInfo
{
public String PNPDeviceID; // 设备ID
public String Name; // 设备名称
public String Description; // 设备描述
public String Service; // 服务
public String Status; // 设备状态
public UInt16 VendorID; // 供应商标识
public UInt16 ProductID; // 产品编号
public Guid ClassGuid; // 设备安装类GUID
} /// <summary>
/// 基于WMI获取USB设备信息
/// </summary>
public partial class USB
{
#region UsbDevice
/// <summary>
/// 获取所有的USB设备实体(过滤没有VID和PID的设备)
/// </summary>
public static PnPEntityInfo[] AllUsbDevices
{
get
{
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
}
} /// <summary>
/// 查询USB设备实体(设备要求有VID和PID)
/// </summary>
/// <param name="VendorID">供应商标识,MinValue忽视</param>
/// <param name="ProductID">产品编号,MinValue忽视</param>
/// <param name="ClassGuid">设备安装类Guid,Empty忽视</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoUsbDevice(UInt16 VendorID, UInt16 ProductID, Guid ClassGuid)
{
List<PnPEntityInfo> UsbDevices = new List<PnPEntityInfo>(); // 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[]; // 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
UInt16 theVendorID = Convert.ToUInt16(match.Value.Substring(, ), ); // 供应商标识
if (VendorID != UInt16.MinValue && VendorID != theVendorID) continue; UInt16 theProductID = Convert.ToUInt16(match.Value.Substring(, ), ); // 产品编号
if (ProductID != UInt16.MinValue && ProductID != theProductID) continue; ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
Guid theClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID
if (ClassGuid != Guid.Empty && ClassGuid != theClassGuid) continue; PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = theVendorID; // 供应商标识
Element.ProductID = theProductID; // 产品编号
Element.ClassGuid = theClassGuid; // 设备安装类GUID UsbDevices.Add(Element);
}
}
}
}
} if (UsbDevices.Count == ) return null; else return UsbDevices.ToArray();
} /// <summary>
/// 查询USB设备实体(设备要求有VID和PID)
/// </summary>
/// <param name="VendorID">供应商标识,MinValue忽视</param>
/// <param name="ProductID">产品编号,MinValue忽视</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoUsbDevice(UInt16 VendorID, UInt16 ProductID)
{
return WhoUsbDevice(VendorID, ProductID, Guid.Empty);
} /// <summary>
/// 查询USB设备实体(设备要求有VID和PID)
/// </summary>
/// <param name="ClassGuid">设备安装类Guid,Empty忽视</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoUsbDevice(Guid ClassGuid)
{
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, ClassGuid);
} /// <summary>
/// 查询USB设备实体(设备要求有VID和PID)
/// </summary>
/// <param name="PNPDeviceID">设备ID,可以是不完整信息</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoUsbDevice(String PNPDeviceID)
{
List<PnPEntityInfo> UsbDevices = new List<PnPEntityInfo>(); // 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[];
if (!String.IsNullOrEmpty(PNPDeviceID))
{ // 注意:忽视大小写
if (Dependent.IndexOf(PNPDeviceID, , PNPDeviceID.Length - , StringComparison.OrdinalIgnoreCase) == -) continue;
} // 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(, ), ); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(, ), ); // 产品编号 // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID UsbDevices.Add(Element);
}
}
}
}
} if (UsbDevices.Count == ) return null; else return UsbDevices.ToArray();
} /// <summary>
/// 根据服务定位USB设备
/// </summary>
/// <param name="ServiceCollection">要查询的服务集合</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoUsbDevice(String[] ServiceCollection)
{
if (ServiceCollection == null || ServiceCollection.Length == )
return WhoUsbDevice(UInt16.MinValue, UInt16.MinValue, Guid.Empty); List<PnPEntityInfo> UsbDevices = new List<PnPEntityInfo>(); // 获取USB控制器及其相关联的设备实体
ManagementObjectCollection USBControllerDeviceCollection = new ManagementObjectSearcher("SELECT * FROM Win32_USBControllerDevice").Get();
if (USBControllerDeviceCollection != null)
{
foreach (ManagementObject USBControllerDevice in USBControllerDeviceCollection)
{ // 获取设备实体的DeviceID
String Dependent = (USBControllerDevice["Dependent"] as String).Split(new Char[] { '=' })[]; // 过滤掉没有VID和PID的USB设备
Match match = Regex.Match(Dependent, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE DeviceID=" + Dependent).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String theService = Entity["Service"] as String; // 服务
if (String.IsNullOrEmpty(theService)) continue; foreach (String Service in ServiceCollection)
{ // 注意:忽视大小写
if (String.Compare(theService, Service, true) != ) continue; PnPEntityInfo Element;
Element.PNPDeviceID = Entity["PNPDeviceID"] as String; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = theService; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(, ), ); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(, ), ); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID UsbDevices.Add(Element);
break;
}
}
}
}
}
} if (UsbDevices.Count == ) return null; else return UsbDevices.ToArray();
}
#endregion #region PnPEntity
/// <summary>
/// 所有即插即用设备实体(过滤没有VID和PID的设备)
/// </summary>
public static PnPEntityInfo[] AllPnPEntities
{
get
{
return WhoPnPEntity(UInt16.MinValue, UInt16.MinValue, Guid.Empty);
}
} /// <summary>
/// 根据VID和PID及设备安装类GUID定位即插即用设备实体
/// </summary>
/// <param name="VendorID">供应商标识,MinValue忽视</param>
/// <param name="ProductID">产品编号,MinValue忽视</param>
/// <param name="ClassGuid">设备安装类Guid,Empty忽视</param>
/// <returns>设备列表</returns>
/// <remarks>
/// HID:{745a17a0-74d3-11d0-b6fe-00a0c90f57da}
/// Imaging Device:{6bdd1fc6-810f-11d0-bec7-08002be2092f}
/// Keyboard:{4d36e96b-e325-11ce-bfc1-08002be10318}
/// Mouse:{4d36e96f-e325-11ce-bfc1-08002be10318}
/// Network Adapter:{4d36e972-e325-11ce-bfc1-08002be10318}
/// USB:{36fc9e60-c465-11cf-8056-444553540000}
/// </remarks>
public static PnPEntityInfo[] WhoPnPEntity(UInt16 VendorID, UInt16 ProductID, Guid ClassGuid)
{
List<PnPEntityInfo> PnPEntities = new List<PnPEntityInfo>(); // 枚举即插即用设备实体
String VIDPID;
if (VendorID == UInt16.MinValue)
{
if (ProductID == UInt16.MinValue)
VIDPID = "'%VID[_]____&PID[_]____%'";
else
VIDPID = "'%VID[_]____&PID[_]" + ProductID.ToString("X4") + "%'";
}
else
{
if (ProductID == UInt16.MinValue)
VIDPID = "'%VID[_]" + VendorID.ToString("X4") + "&PID[_]____%'";
else
VIDPID = "'%VID[_]" + VendorID.ToString("X4") + "&PID[_]" + ProductID.ToString("X4") + "%'";
} String QueryString;
if (ClassGuid == Guid.Empty)
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE" + VIDPID;
else
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE" + VIDPID + " AND ClassGuid='" + ClassGuid.ToString("B") + "'"; ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher(QueryString).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String PNPDeviceID = Entity["PNPDeviceID"] as String;
Match match = Regex.Match(PNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
PnPEntityInfo Element; Element.PNPDeviceID = PNPDeviceID; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(, ), ); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(, ), ); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID PnPEntities.Add(Element);
}
}
} if (PnPEntities.Count == ) return null; else return PnPEntities.ToArray();
} /// <summary>
/// 根据VID和PID定位即插即用设备实体
/// </summary>
/// <param name="VendorID">供应商标识,MinValue忽视</param>
/// <param name="ProductID">产品编号,MinValue忽视</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoPnPEntity(UInt16 VendorID, UInt16 ProductID)
{
return WhoPnPEntity(VendorID, ProductID, Guid.Empty);
} /// <summary>
/// 根据设备安装类GUID定位即插即用设备实体
/// </summary>
/// <param name="ClassGuid">设备安装类Guid,Empty忽视</param>
/// <returns>设备列表</returns>
public static PnPEntityInfo[] WhoPnPEntity(Guid ClassGuid)
{
return WhoPnPEntity(UInt16.MinValue, UInt16.MinValue, ClassGuid);
} /// <summary>
/// 根据设备ID定位设备
/// </summary>
/// <param name="PNPDeviceID">设备ID,可以是不完整信息</param>
/// <returns>设备列表</returns>
/// <remarks>
/// 注意:对于下划线,需要写成“[_]”,否则视为任意字符
/// </remarks>
public static PnPEntityInfo[] WhoPnPEntity(String PNPDeviceID)
{
List<PnPEntityInfo> PnPEntities = new List<PnPEntityInfo>(); // 枚举即插即用设备实体
String QueryString;
if (String.IsNullOrEmpty(PNPDeviceID))
{
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE '%VID[_]____&PID[_]____%'";
}
else
{ // LIKE子句中有反斜杠字符将会引发WQL查询异常
QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE '%" + PNPDeviceID.Replace('\\', '_') + "%'";
} ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher(QueryString).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String thePNPDeviceID = Entity["PNPDeviceID"] as String;
Match match = Regex.Match(thePNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
PnPEntityInfo Element; Element.PNPDeviceID = thePNPDeviceID; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = Entity["Service"] as String; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(, ), ); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(, ), ); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID PnPEntities.Add(Element);
}
}
} if (PnPEntities.Count == ) return null; else return PnPEntities.ToArray();
} /// <summary>
/// 根据服务定位设备
/// </summary>
/// <param name="ServiceCollection">要查询的服务集合,null忽视</param>
/// <returns>设备列表</returns>
/// <remarks>
/// 跟服务相关的类:
/// Win32_SystemDriverPNPEntity
/// Win32_SystemDriver
/// </remarks>
public static PnPEntityInfo[] WhoPnPEntity(String[] ServiceCollection)
{
if (ServiceCollection == null || ServiceCollection.Length == )
return WhoPnPEntity(UInt16.MinValue, UInt16.MinValue, Guid.Empty); List<PnPEntityInfo> PnPEntities = new List<PnPEntityInfo>(); // 枚举即插即用设备实体
String QueryString = "SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE '%VID[_]____&PID[_]____%'";
ManagementObjectCollection PnPEntityCollection = new ManagementObjectSearcher(QueryString).Get();
if (PnPEntityCollection != null)
{
foreach (ManagementObject Entity in PnPEntityCollection)
{
String PNPDeviceID = Entity["PNPDeviceID"] as String;
Match match = Regex.Match(PNPDeviceID, "VID_[0-9|A-F]{4}&PID_[0-9|A-F]{4}");
if (match.Success)
{
String theService = Entity["Service"] as String; // 服务
if (String.IsNullOrEmpty(theService)) continue; foreach (String Service in ServiceCollection)
{ // 注意:忽视大小写
if (String.Compare(theService, Service, true) != ) continue; PnPEntityInfo Element; Element.PNPDeviceID = PNPDeviceID; // 设备ID
Element.Name = Entity["Name"] as String; // 设备名称
Element.Description = Entity["Description"] as String; // 设备描述
Element.Service = theService; // 服务
Element.Status = Entity["Status"] as String; // 设备状态
Element.VendorID = Convert.ToUInt16(match.Value.Substring(, ), ); // 供应商标识
Element.ProductID = Convert.ToUInt16(match.Value.Substring(, ), ); // 产品编号
Element.ClassGuid = new Guid(Entity["ClassGuid"] as String); // 设备安装类GUID PnPEntities.Add(Element);
break;
}
}
}
} if (PnPEntities.Count == ) return null; else return PnPEntities.ToArray();
}
#endregion
}
}
Android设备厂商VID列表 :
http://developer.android.com/tools/device.html
Company | USB Vendor ID |
---|---|
Acer | 0502 |
ASUS | 0b05 |
Dell | 413c |
Foxconn | 0489 |
Fujitsu | 04c5 |
Fujitsu Toshiba | 04c5 |
Garmin-Asus | 091e |
18d1 |
|
Haier | 201E |
Hisense | 109b |
HTC | 0bb4 |
Huawei | 12d1 |
K-Touch | 24e3 |
KT Tech | 2116 |
Kyocera | 0482 |
Lenovo | 17ef |
LG | 1004 |
Motorola | 22b8 |
MTK | 0e8d |
NEC | 0409 |
Nook | 2080 |
Nvidia | 0955 |
OTGV | 2257 |
Pantech | 10a9 |
Pegatron | 1d4d |
Philips | 0471 |
PMC-Sierra | 04da |
Qualcomm | 05c6 |
SK Telesys | 1f53 |
Samsung | 04e8 |
Sharp | 04dd |
Sony | 054c |
Sony Ericsson | 0fce |
Teleepoch | 2340 |
Toshiba | 0930 |
ZTE | 19d2 |
C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表的更多相关文章
- C#:基于WMI查询USB设备
来源:http://blog.csdn.net/jhqin/article/details/6734673 /* ------------------------------------------- ...
- C# 获取USB设备信息
C# 获取USB设备信息WMI方式 using System; using System.Management; using System.Text.RegularExpressions; using ...
- 如何查看USB方式连接Android设备的外接设备信息
1,USB存储设备(如:U盘,移动硬盘): //USB存储设备 插拔监听与 SD卡插拔监听一致. private USBBroadCastReceiver mBroadcastReceiver; In ...
- Linux Platform驱动模型(一)-设备信息
我在Linux字符设备驱动框架一文中简单介绍了Linux字符设备编程模型,在那个模型中,只要应用程序open()了相应的设备文件,就可以使用ioctl通过驱动程序来控制我们的硬件,这种模型直观,但是从 ...
- iOS开发的另类神器:libimobiledevice开源包【类似android adb 方便获取iOS设备信息】
简介 libimobiledevice又称libiphone,是一个开源包,可以让Linux支持连接iPhone/iPod Touch等iOS设备.由于苹果官方并不支持Linux系统,但是Linux上 ...
- Linux Platform驱动模型(一) _设备信息
我在Linux字符设备驱动框架一文中简单介绍了Linux字符设备编程模型,在那个模型中,只要应用程序open()了相应的设备文件,就可以使用ioctl通过驱动程序来控制我们的硬件,这种模型直观,但是从 ...
- ?Swift获取手机设备信息
使用UiDevice获取设备信息: 获取设备名称 let name = UIDevice.currentDevice().name 获取设备系统名称 let systemName = UIDevice ...
- [转载]iOS开发:获取设备信息
开发iOS平台的应用的时候,可以获取iOS设备的设备信息,包括设备的名称,设备的机型,设备的iOS版本等等.设备信息主要来自 UIDevice 类. UIDevice *currentDevice = ...
- 微信小程序把玩(三十八)获取设备信息 API
原文:微信小程序把玩(三十八)获取设备信息 API 获取设备信息这里分为四种, 主要属性: 网络信息wx.getNetWorkType, 系统信息wx.getSystemInfo, 重力感应数据wx. ...
随机推荐
- [异常解决] MPU6050启动异常读出陀螺仪和加速度计的值全为0的解决办法
在调试一个自己做的手环,每次用keil烧写好程序运行的蓝牙.陀螺仪都是正常的.但是掉电再上电之后蓝牙是好的.陀螺仪可以读出ID但是读出的加速度和角速度数据全为0. 下面是发生问题时main函数的前面部 ...
- osgi 1
Helloworld入门 准备: eclipse 3.4 需要jar,—— eclipse 自带的,plugin下面有很多,抛开里面的jar,很多都是当前项目不需要的,如果不适用eclipse而是直接 ...
- java加密-解密小结
加密算法可以分为 双向加密(对称加密.不对称加密) 单向加密(不可逆加密)—— MD5.sha.hmac... 在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密 有: ...
- 【团队分享之二】IT团队绩效提升的一些见解
- Hibernate中对象的三个状态解析
Hibernate 将操作的对象分为三种状态: 1. 瞬时 (Transient )/临时状态/自由状态 持久 (Persistent) 脱管 (Detached) 瞬时对象特征: 第一.不处于 Se ...
- 缓存篇~第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存
返回目录 这一讲中主要是说EnterpriseLibrary企业级架构里的caching组件,它主要实现了项目缓存功能,它支持四种持久化方式,内存,文件,数据库和自定义,对于持久化不是今天讨论的重要, ...
- Python为什么不隐式实现self
Python为什么不隐式实现self Python中类的方法都需要显式的传入一个self占位参数,这让写过C#,Java,PHP,Javascript的我很是不习惯,但是Python这么吊,肯定是有他 ...
- KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑
在典型的Knockout应用程序中,DOM元素是动态添加和删除的,例如使用模板绑定或通过控制流绑定(if,ifnot,with和foreach). 当创建自定义绑定时,通常需要添加清除逻辑,当Knoc ...
- mac本用WTG(Windows To Go)安装Win10到移动硬盘
准备工作: 一个空的 USB 3.0 移动硬盘(在安装 WTG 时候会将这个硬盘清空重新并分区,注意备份好数据.USB 3.0 的优盘是不行的,即使安装成功,系统的运行速度会奇慢) 原版Windows ...
- 让BI告诉你:圣诞老人去哪了?
刚看到一篇关于圣诞节BI分析的文章,觉得很有意思,特来翻译了下和大家一起分享(可惜的是文章发布的时间有点久). 伴随着圣诞节即将到来的日子,POWER BI团队来回答大家最为关注的一个问题:圣诞老人到 ...