首先,这是背景:
我们有一个 Windows 窗体应用程序(用 C#、.NET Framework 3.5 编写)当前运行在完整的 Windows 7 平板电脑上,它内置了一个用于数据连接的 3G 模块。数据连接在 Windows 中配置为普通移动宽带连接(因此 Windows 自行管理连接),并且连接显示在控制面板 > 网络和 Internet > 网络连接中并且工作正常 - 应用程序能够通过使用我们的网络服务上网。我们将在未来的某个时候转移到不同的设备(可能是基于 Windows 8 的完整平板电脑)。
现在,我需要做的是读取这个移动宽带连接的连接状态;即获取信号强度和运营商名称(例如 Vodafone UK)。我找到了一种使用 Windows 7 SDK 的移动宽带 API 部分执行此操作的方法(请参阅 here 和 here ),但这似乎是特定于操作系统的,因为它不适用于 Windows 8 - 或者在至少我这里的设备不行。
是否有使用 .NET 框架读取移动宽带连接属性的通用方法?
或者,有人知道像我目前使用的 Windows 7 那样包含移动宽带 API 的 Windows 8 SDK 吗?
提前致谢。
更新 - 我现在可以在一系列不同的 Win 7/Win 8 设备上使用它。即使是联想设备也能正常工作。我将发布主要部分的示例代码(读取连接状态、配置连接、检查 SIM 卡状态)作为答案;代码有点太长了,无法进入这个问题,这很烦人。
最佳答案
以编程方式配置连接(您将需要 APN 详细信息):
try
{
MbnInterfaceManager mbnInfMgr = new MbnInterfaceManager();
IMbnInterfaceManager mbnInfMgrInterface = mbnInfMgr as IMbnInterfaceManager;
if (mbnInfMgrInterface != null)
{
IMbnInterface[] mobileInterfaces = mbnInfMgrInterface.GetInterfaces() as IMbnInterface[];
if (mobileInterfaces != null && mobileInterfaces.Length > 0)
{
// Just use the first interface
IMbnSubscriberInformation subInfo = mobileInterfaces[0].GetSubscriberInformation();
if (subInfo != null)
{
SIMNumber = subInfo.SimIccID;
// Get the connection profile
MbnConnectionProfileManager mbnConnProfileMgr = new MbnConnectionProfileManager();
IMbnConnectionProfileManager mbnConnProfileMgrInterface = mbnConnProfileMgr as IMbnConnectionProfileManager;
if (mbnConnProfileMgrInterface != null)
{
bool connProfileFound = false;
string profileName = String.Empty;
try
{
IMbnConnectionProfile[] mbnConnProfileInterfaces = mbnConnProfileMgrInterface.GetConnectionProfiles(mobileInterfaces[0]) as IMbnConnectionProfile[];
foreach (IMbnConnectionProfile profile in mbnConnProfileInterfaces)
{
string xmlData = profile.GetProfileXmlData();
if (xmlData.Contains("<SimIccID>" + SIMNumber + "</SimIccID>"))
{
connProfileFound = true;
bool updateRequired = false;
// Check if the profile is set to auto connect
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xmlData);
profileName = xdoc["MBNProfile"]["Name"].InnerText;
if (xdoc["MBNProfile"]["ConnectionMode"].InnerText != "auto")
{
xdoc["MBNProfile"]["ConnectionMode"].InnerText = "auto";
updateRequired = true;
}
// Check the APN settings
if (xdoc["MBNProfile"]["Context"] == null)
{
XmlElement context = (XmlElement)xdoc["MBNProfile"].AppendChild(xdoc.CreateElement("Context", xdoc["MBNProfile"].NamespaceURI));
context.AppendChild(xdoc.CreateElement("AccessString", xdoc["MBNProfile"].NamespaceURI));
context.AppendChild(xdoc.CreateElement("Compression", xdoc["MBNProfile"].NamespaceURI));
context.AppendChild(xdoc.CreateElement("AuthProtocol", xdoc["MBNProfile"].NamespaceURI));
updateRequired = true;
}
if (xdoc["MBNProfile"]["Context"]["AccessString"].InnerText != APNAccessString)
{
xdoc["MBNProfile"]["Context"]["AccessString"].InnerText = APNAccessString;
updateRequired = true;
}
if (xdoc["MBNProfile"]["Context"]["Compression"].InnerText != APNCompression)
{
xdoc["MBNProfile"]["Context"]["Compression"].InnerText = APNCompression;
updateRequired = true;
}
if (xdoc["MBNProfile"]["Context"]["AuthProtocol"].InnerText != APNAuthProtocol)
{
xdoc["MBNProfile"]["Context"]["AuthProtocol"].InnerText = APNAuthProtocol;
updateRequired = true;
}
if (xdoc["MBNProfile"]["Context"]["UserLogonCred"] == null && !String.IsNullOrEmpty(APNUsername))
{
XmlElement userLogonCred = (XmlElement)xdoc["MBNProfile"]["Context"].InsertAfter(xdoc.CreateElement("UserLogonCred", xdoc["MBNProfile"].NamespaceURI), xdoc["MBNProfile"]["Context"]["AccessString"]);
userLogonCred.AppendChild(xdoc.CreateElement("UserName", xdoc["MBNProfile"].NamespaceURI));
userLogonCred.AppendChild(xdoc.CreateElement("Password", xdoc["MBNProfile"].NamespaceURI));
updateRequired = true;
}
if (xdoc["MBNProfile"]["Context"]["UserLogonCred"] != null && xdoc["MBNProfile"]["Context"]["UserLogonCred"]["UserName"].InnerText != APNUsername)
{
xdoc["MBNProfile"]["Context"]["UserLogonCred"]["UserName"].InnerText = APNUsername;
updateRequired = true;
}
if (xdoc["MBNProfile"]["Context"]["UserLogonCred"] != null && xdoc["MBNProfile"]["Context"]["UserLogonCred"]["Password"] == null && !String.IsNullOrEmpty(APNUsername))
{
xdoc["MBNProfile"]["Context"]["UserLogonCred"].AppendChild(xdoc.CreateElement("Password", xdoc["MBNProfile"].NamespaceURI));
}
if (xdoc["MBNProfile"]["Context"]["UserLogonCred"] != null && xdoc["MBNProfile"]["Context"]["UserLogonCred"]["Password"].InnerText != APNPassword)
{
xdoc["MBNProfile"]["Context"]["UserLogonCred"]["Password"].InnerText = APNPassword;
updateRequired = true;
}
if (updateRequired)
{
// Update the connection profile
profile.UpdateProfile(xdoc.OuterXml);
}
}
}
}
catch (Exception ex)
{
if (!ex.Message.Contains("Element not found"))
{
throw ex;
}
}
if (!connProfileFound)
{
// Create the connection profile
XmlDocument xdoc = new XmlDocument();
xdoc.AppendChild(xdoc.CreateXmlDeclaration("1.0", "utf-8", "yes"));
XmlElement mbnProfile = (XmlElement)xdoc.AppendChild(xdoc.CreateElement("MBNProfile", "http://www.microsoft.com/networking/WWAN/profile/v1"));
mbnProfile.AppendChild(xdoc.CreateElement("Name", xdoc["MBNProfile"].NamespaceURI)).InnerText = SIMNumber;
mbnProfile.AppendChild(xdoc.CreateElement("IsDefault", xdoc["MBNProfile"].NamespaceURI)).InnerText = "true";
mbnProfile.AppendChild(xdoc.CreateElement("ProfileCreationType", xdoc["MBNProfile"].NamespaceURI)).InnerText = "DeviceProvisioned";
mbnProfile.AppendChild(xdoc.CreateElement("SubscriberID", xdoc["MBNProfile"].NamespaceURI)).InnerText = subInfo.SubscriberID;
mbnProfile.AppendChild(xdoc.CreateElement("SimIccID", xdoc["MBNProfile"].NamespaceURI)).InnerText = SIMNumber;
mbnProfile.AppendChild(xdoc.CreateElement("HomeProviderName", xdoc["MBNProfile"].NamespaceURI)).InnerText = SIMNumber;
mbnProfile.AppendChild(xdoc.CreateElement("AutoConnectOnInternet", xdoc["MBNProfile"].NamespaceURI)).InnerText = "true";
mbnProfile.AppendChild(xdoc.CreateElement("ConnectionMode", xdoc["MBNProfile"].NamespaceURI)).InnerText = "auto";
XmlElement context = (XmlElement)xdoc["MBNProfile"].AppendChild(xdoc.CreateElement("Context", xdoc["MBNProfile"].NamespaceURI));
context.AppendChild(xdoc.CreateElement("AccessString", xdoc["MBNProfile"].NamespaceURI));
XmlElement userLogonCred = (XmlElement)context.AppendChild(xdoc.CreateElement("UserLogonCred", xdoc["MBNProfile"].NamespaceURI));
userLogonCred.AppendChild(xdoc.CreateElement("UserName", xdoc["MBNProfile"].NamespaceURI));
userLogonCred.AppendChild(xdoc.CreateElement("Password", xdoc["MBNProfile"].NamespaceURI));
context.AppendChild(xdoc.CreateElement("Compression", xdoc["MBNProfile"].NamespaceURI));
context.AppendChild(xdoc.CreateElement("AuthProtocol", xdoc["MBNProfile"].NamespaceURI));
xdoc["MBNProfile"]["Context"]["AccessString"].InnerText = APNAccessString;
xdoc["MBNProfile"]["Context"]["UserLogonCred"]["UserName"].InnerText = APNUsername;
xdoc["MBNProfile"]["Context"]["UserLogonCred"]["Password"].InnerText = APNPassword;
xdoc["MBNProfile"]["Context"]["Compression"].InnerText = APNCompression;
xdoc["MBNProfile"]["Context"]["AuthProtocol"].InnerText = APNAuthProtocol;
profileName = xdoc["MBNProfile"]["Name"].InnerText;
mbnConnProfileMgrInterface.CreateConnectionProfile(xdoc.OuterXml);
}
// Register the connection events
MbnConnectionManager connMgr = new MbnConnectionManager();
IConnectionPointContainer connPointContainer = connMgr as IConnectionPointContainer;
Guid IID_IMbnConnectionEvents = typeof(IMbnConnectionEvents).GUID;
IConnectionPoint connPoint;
connPointContainer.FindConnectionPoint(ref IID_IMbnConnectionEvents, out connPoint);
ConnectionEventsSink connEventsSink = new ConnectionEventsSink();
connPoint.Advise(connEventsSink, out cookie); if (showProgress) { MessageBox.Show("After registering events"); }
// Connect
IMbnConnection connection = mobileInterfaces[0].GetConnection();
if (connection != null)
{
MBN_ACTIVATION_STATE state;
string connectionProfileName = String.Empty;
connection.GetConnectionState(out state, out connectionProfileName);
if (state != MBN_ACTIVATION_STATE.MBN_ACTIVATION_STATE_ACTIVATED && state != MBN_ACTIVATION_STATE.MBN_ACTIVATION_STATE_ACTIVATING)
{
if (String.IsNullOrEmpty(connectionProfileName))
{
connectionProfileName = profileName;
}
uint requestID;
connection.Connect(MBN_CONNECTION_MODE.MBN_CONNECTION_MODE_PROFILE, connectionProfileName, out requestID);
}
else
{
// Do nothing, already connected
}
}
else
{
MessageBox.Show("Connection not found.");
}
}
else
{
MessageBox.Show("mbnConnProfileMgrInterface is null.");
}
}
else
{
MessageBox.Show("No subscriber info found.");
}
}
else
{
MessageBox.Show("No mobile interfaces found.");
}
}
else
{
MessageBox.Show("mbnInfMgrInterface is null.");
}
}
catch (Exception ex)
{
if (ex.Message.Contains("SIM is not inserted."))
{
SIMNumber = "No SIM inserted.";
}
MessageBox.Show("LoginForm.DataConnection ConfigureWindowsDataConnection Error " + ex.Message);
}
关于C# 读取 Windows Mobile 宽带连接属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18577510/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2
我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL