以下程序在模拟器上测试成功,但在现实中的手机SIM卡上并未写入本机号码,可能读不出来。
#region Sim Class
/// <summary> Reads information from the Subscriber Identity Module (SIM) </summary>
public class Sim
{
#region Sim P/Invoke
private static long SERVICE_PROVIDER = 0x00006F46;
private static long SIM_NUMSMSSTORAGES = 2;
private static int SIM_PBSTORAGE_SIM = 0x10; //
/// <summary> Reads information from the Subscriber Identity Module (SIM) </summary>
public class Sim
{
#region Sim P/Invoke
private static long SERVICE_PROVIDER = 0x00006F46;
private static long SIM_NUMSMSSTORAGES = 2;
private static int SIM_PBSTORAGE_SIM = 0x10; //
#region 结构
[StructLayout(LayoutKind.Sequential)]
private struct SimRecord
{
public IntPtr cbSize;
public IntPtr dwParams;
public IntPtr dwRecordType;
public IntPtr dwItemCount;
public IntPtr dwSize;
}
[StructLayout(LayoutKind.Sequential)]
private struct SimRecord
{
public IntPtr cbSize;
public IntPtr dwParams;
public IntPtr dwRecordType;
public IntPtr dwItemCount;
public IntPtr dwSize;
}
[StructLayout(LayoutKind.Sequential)]
public struct SimMessageTag
{
public IntPtr cbSize; // Size of the structure in bytes
public IntPtr dwParams; //Indicates valid parameter values
/// <summary> 发信人 </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszAddress; //An array that contains the actual phone number
public IntPtr dwAddressType; //A SIM_ADDRTYPE constant
public IntPtr dwNumPlan; //A SIM_NUMPLAN constant
/// <summary> 收到时间 </summary>
public SystemTime stReceiveTime; //Timestamp for the incoming message
public IntPtr cbHdrLength; //Header length in bytes
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] rgbHeader; //An array containing the actual header data
/// <summary> 短信内容 </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszMessage; //An array containing the actual message data
}
public struct SimMessageTag
{
public IntPtr cbSize; // Size of the structure in bytes
public IntPtr dwParams; //Indicates valid parameter values
/// <summary> 发信人 </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszAddress; //An array that contains the actual phone number
public IntPtr dwAddressType; //A SIM_ADDRTYPE constant
public IntPtr dwNumPlan; //A SIM_NUMPLAN constant
/// <summary> 收到时间 </summary>
public SystemTime stReceiveTime; //Timestamp for the incoming message
public IntPtr cbHdrLength; //Header length in bytes
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] rgbHeader; //An array containing the actual header data
/// <summary> 短信内容 </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszMessage; //An array containing the actual message data
}
[StructLayout(LayoutKind.Sequential)]
public struct SystemTime
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
public struct SystemTime
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
public SystemTime(System.DateTime now)
{
wYear = (short)now.Year;
wMonth = (short)now.Month;
wDayOfWeek = (short)now.DayOfWeek;
wDay = (short)now.Day;
wHour = (short)now.Hour;
wMinute = (short)now.Minute;
wSecond = (short)now.Second;
wMilliseconds = (short)now.Millisecond;
}
public override string ToString()
{
return string.Format("{0}/{1}/{2}", wYear, wMonth, wDay);
}
}
{
wYear = (short)now.Year;
wMonth = (short)now.Month;
wDayOfWeek = (short)now.DayOfWeek;
wDay = (short)now.Day;
wHour = (short)now.Hour;
wMinute = (short)now.Minute;
wSecond = (short)now.Second;
wMilliseconds = (short)now.Millisecond;
}
public override string ToString()
{
return string.Format("{0}/{1}/{2}", wYear, wMonth, wDay);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SIMPHONEBOOKENTRY
{
public uint cbSize; //
public uint dwParams; //
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszAddress; // 联系人电话
public uint dwAddressType; //
public uint dwNumPlan; //
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszText; // 联系人姓名
}
#endregion
public struct SIMPHONEBOOKENTRY
{
public uint cbSize; //
public uint dwParams; //
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszAddress; // 联系人电话
public uint dwAddressType; //
public uint dwNumPlan; //
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string lpszText; // 联系人姓名
}
#endregion
#region dll call wrapper
[DllImport("sms.dll")]
private static extern IntPtr SmsGetPhoneNumber(IntPtr psmsaAddress);
[DllImport("sms.dll")]
private static extern IntPtr SmsGetPhoneNumber(IntPtr psmsaAddress);
[DllImport("cellcore.dll")]
private static extern IntPtr SimInitialize(IntPtr dwFlags, IntPtr lpfnCallBack, IntPtr dwParam, out IntPtr lphSim);
private static extern IntPtr SimInitialize(IntPtr dwFlags, IntPtr lpfnCallBack, IntPtr dwParam, out IntPtr lphSim);
[DllImport("cellcore.dll")]
private static extern IntPtr SimGetRecordInfo(IntPtr hSim, IntPtr dwAddress, ref SimRecord lpSimRecordInfo);
private static extern IntPtr SimGetRecordInfo(IntPtr hSim, IntPtr dwAddress, ref SimRecord lpSimRecordInfo);
[DllImport("cellcore.dll")]
private static extern IntPtr SimReadRecord(IntPtr hSim, IntPtr dwAddress, IntPtr dwRecordType, IntPtr dwIndex, byte[] lpData, IntPtr dwBufferSize, ref IntPtr lpdwBytesRead);
private static extern IntPtr SimReadRecord(IntPtr hSim, IntPtr dwAddress, IntPtr dwRecordType, IntPtr dwIndex, byte[] lpData, IntPtr dwBufferSize, ref IntPtr lpdwBytesRead);
[DllImport("cellcore.dll")]
private static extern IntPtr SimDeinitialize(IntPtr hSim );
private static extern IntPtr SimDeinitialize(IntPtr hSim );
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimGetSmsStorageStatus(IntPtr hSim, IntPtr dwStorage, ref IntPtr lpdwUsed, ref IntPtr lpdwTotal);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimWriteMessage(IntPtr hSim, IntPtr dwStorage, ref IntPtr lpdwIndex, ref SimMessageTag SmsStructType);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimReadMessage(IntPtr hSim, IntPtr dwStorage, IntPtr lpdwIndex, ref SimMessageTag SmsStructType);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimDeleteMessage(IntPtr hSim, IntPtr dwStorage, ref IntPtr lpdwIndex);
private static extern IntPtr SimGetSmsStorageStatus(IntPtr hSim, IntPtr dwStorage, ref IntPtr lpdwUsed, ref IntPtr lpdwTotal);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimWriteMessage(IntPtr hSim, IntPtr dwStorage, ref IntPtr lpdwIndex, ref SimMessageTag SmsStructType);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimReadMessage(IntPtr hSim, IntPtr dwStorage, IntPtr lpdwIndex, ref SimMessageTag SmsStructType);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimDeleteMessage(IntPtr hSim, IntPtr dwStorage, ref IntPtr lpdwIndex);
[DllImport("cellcore.dll", SetLastError = true)]
private static extern IntPtr SimReadPhonebookEntry(IntPtr hSim, IntPtr dwLocation, IntPtr dwIndex, ref SIMPHONEBOOKENTRY lpPhonebookEntry);
private static extern IntPtr SimReadPhonebookEntry(IntPtr hSim, IntPtr dwLocation, IntPtr dwIndex, ref SIMPHONEBOOKENTRY lpPhonebookEntry);
[DllImport("cellcore.dll")]
private static extern IntPtr SimGetPhonebookStatus(IntPtr hSim, IntPtr dwLocation, ref IntPtr lpdwUsed, ref IntPtr lpdwTotal);
private static extern IntPtr SimGetPhonebookStatus(IntPtr hSim, IntPtr dwLocation, ref IntPtr lpdwUsed, ref IntPtr lpdwTotal);
#endregion
#endregion
#region 从SIM卡获得手机本机号码
/// <summary>
/// Gets the phone number from the SIM.
/// </summary>
/// <returns>PhoneAddress structure with phone number.</returns>
unsafe public static PhoneAddress GetPhoneNumber()
{
PhoneAddress phoneaddr = new PhoneAddress();
/// <summary>
/// Gets the phone number from the SIM.
/// </summary>
/// <returns>PhoneAddress structure with phone number.</returns>
unsafe public static PhoneAddress GetPhoneNumber()
{
PhoneAddress phoneaddr = new PhoneAddress();
Byte[] buffer = new Byte[516];
fixed (byte* pAddr = buffer)
{
IntPtr res = SmsGetPhoneNumber((IntPtr)pAddr);
if (res != IntPtr.Zero)
throw new Exception("Could not get phone number from SIM");
fixed (byte* pAddr = buffer)
{
IntPtr res = SmsGetPhoneNumber((IntPtr)pAddr);
if (res != IntPtr.Zero)
throw new Exception("Could not get phone number from SIM");
byte *pCurrent = pAddr;
phoneaddr.AddressType = (AddressType)Marshal.ReadInt32((IntPtr)pCurrent);
pCurrent += Marshal.SizeOf(phoneaddr.AddressType);
phoneaddr.Address = Marshal.PtrToStringUni((IntPtr)pCurrent);
}
phoneaddr.AddressType = (AddressType)Marshal.ReadInt32((IntPtr)pCurrent);
pCurrent += Marshal.SizeOf(phoneaddr.AddressType);
phoneaddr.Address = Marshal.PtrToStringUni((IntPtr)pCurrent);
}
return phoneaddr;
}
#endregion
}
#endregion
#region 从SIM卡获得当前无线运营网络提供商
/// <summary>
/// Gets the current wireless carriers network name from the SIM.
/// </summary>
/// <returns>The carrier description.</returns>
public static string GetServiceProvider()
{
IntPtr hSim, res;
/// <summary>
/// Gets the current wireless carriers network name from the SIM.
/// </summary>
/// <returns>The carrier description.</returns>
public static string GetServiceProvider()
{
IntPtr hSim, res;
res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);
if (res != IntPtr.Zero)
throw new Exception("Could not initialize SIM");
if (res != IntPtr.Zero)
throw new Exception("Could not initialize SIM");
SimRecord rec = new SimRecord();
rec.cbSize = (IntPtr)Marshal.SizeOf(rec);
rec.cbSize = (IntPtr)Marshal.SizeOf(rec);
res = SimGetRecordInfo(hSim, (IntPtr)SERVICE_PROVIDER, ref rec);
if (res != IntPtr.Zero)
throw new Exception("Could not read the service provider information from the SIM");
if (res != IntPtr.Zero)
throw new Exception("Could not read the service provider information from the SIM");
byte[] bData = new byte[(int)rec.dwSize + 1];
IntPtr dwBytesRead = IntPtr.Zero;
IntPtr dwBytesRead = IntPtr.Zero;
res = SimReadRecord(hSim, (IntPtr)SERVICE_PROVIDER, rec.dwRecordType, IntPtr.Zero, bData, (IntPtr)bData.Length, ref dwBytesRead);
if (res != IntPtr.Zero)
throw new Exception("Could not read the service provider from the SIM");
if (res != IntPtr.Zero)
throw new Exception("Could not read the service provider from the SIM");
byte[] bScrubbed = new byte[(int)dwBytesRead];
int nPos = 0;
int nPos = 0;
// Scrub the non-ascii characters
for (int i = 0; i < (int)dwBytesRead; i ++)
{
if (((int)bData[i] > 19) && ((int)bData[i] < 125))
{
bScrubbed[nPos] = bData[i];
nPos++;
}
}
for (int i = 0; i < (int)dwBytesRead; i ++)
{
if (((int)bData[i] > 19) && ((int)bData[i] < 125))
{
bScrubbed[nPos] = bData[i];
nPos++;
}
}
SimDeinitialize(hSim);
return Encoding.ASCII.GetString(bScrubbed, 0, bScrubbed.Length);
}
#endregion
}
#endregion
#region 短信息
public static SimMessageTag[] GetSimMessages(out int totalSize)
{
IntPtr hSim, res;
IntPtr ipStorage = new IntPtr(SIM_NUMSMSSTORAGES);
public static SimMessageTag[] GetSimMessages(out int totalSize)
{
IntPtr hSim, res;
IntPtr ipStorage = new IntPtr(SIM_NUMSMSSTORAGES);
#region 初始化
res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);
if (res != IntPtr.Zero)
throw new Exception("Could not initialize SIM");
#endregion
res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);
if (res != IntPtr.Zero)
throw new Exception("Could not initialize SIM");
#endregion
#region SimGetSmsStorageStatus
IntPtr used = IntPtr.Zero, total = IntPtr.Zero;
res = SimGetSmsStorageStatus(hSim, ipStorage, ref used, ref total);
IntPtr used = IntPtr.Zero, total = IntPtr.Zero;
res = SimGetSmsStorageStatus(hSim, ipStorage, ref used, ref total);
if (res != IntPtr.Zero)
throw new Exception(Marshal.GetLastWin32Error().ToString());
throw new Exception(Marshal.GetLastWin32Error().ToString());
totalSize = total.ToInt32();
#endregion
#endregion
#region SimReadMessage
SimMessageTag[] retMsgs = new SimMessageTag[used.ToInt32()];
for (int j = 1; j <= used.ToInt32(); j++)
{
SimMessageTag message = new SimMessageTag();
res = SimReadMessage(hSim, ipStorage, new IntPtr(j), ref message);
if (res == IntPtr.Zero)
{
retMsgs[j - 1] = message;
}
}
#endregion
SimMessageTag[] retMsgs = new SimMessageTag[used.ToInt32()];
for (int j = 1; j <= used.ToInt32(); j++)
{
SimMessageTag message = new SimMessageTag();
res = SimReadMessage(hSim, ipStorage, new IntPtr(j), ref message);
if (res == IntPtr.Zero)
{
retMsgs[j - 1] = message;
}
}
#endregion
SimDeinitialize(hSim);
return retMsgs;
}
#endregion
}
#endregion
#region 通讯录
public static List<SIMPHONEBOOKENTRY> GetSimPhoneBook()
{
#region 初始化
IntPtr hSim, res;
res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);
if (res != IntPtr.Zero)
throw new Exception("Could not initialize SIM");
#endregion
public static List<SIMPHONEBOOKENTRY> GetSimPhoneBook()
{
#region 初始化
IntPtr hSim, res;
res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);
if (res != IntPtr.Zero)
throw new Exception("Could not initialize SIM");
#endregion
IntPtr usedLocations = IntPtr.Zero; //Number of locations used
IntPtr totalCapicity = IntPtr.Zero; //Total number of locations
IntPtr totalCapicity = IntPtr.Zero; //Total number of locations
res = SimGetPhonebookStatus(hSim, (IntPtr)SIM_PBSTORAGE_SIM, ref usedLocations, ref totalCapicity);
List<SIMPHONEBOOKENTRY> contracts = new List<SIMPHONEBOOKENTRY>();
if (res == IntPtr.Zero)
{
for (int i = 1; i <= usedLocations.ToInt32(); i++)
{
SIMPHONEBOOKENTRY entry = new SIMPHONEBOOKENTRY();
entry.cbSize = (uint)Marshal.SizeOf(typeof(SIMPHONEBOOKENTRY));
res = SimReadPhonebookEntry(hSim, (IntPtr)SIM_PBSTORAGE_SIM, (IntPtr)i, ref entry);
contracts.Add(entry);
}
}
if (res == IntPtr.Zero)
{
for (int i = 1; i <= usedLocations.ToInt32(); i++)
{
SIMPHONEBOOKENTRY entry = new SIMPHONEBOOKENTRY();
entry.cbSize = (uint)Marshal.SizeOf(typeof(SIMPHONEBOOKENTRY));
res = SimReadPhonebookEntry(hSim, (IntPtr)SIM_PBSTORAGE_SIM, (IntPtr)i, ref entry);
contracts.Add(entry);
}
}
SimDeinitialize(hSim);
return contracts;
}
#endregion
}
#endregion
}
#endregion
}
#endregion