如何判断连接是否计量?

14

我写了一个程序来监控IMAP电子邮件账户。它按计划在我随身携带的笔记本电脑上运行。有时,当我的互联网连接是通过移动设备时(即,我按GB计费),它也会运行,但我不希望它这样做,因为它会使用大量带宽,所以可以等到带宽空闲再运行。

那么问题来了:.NET程序如何确定它正在使用的连接是否是按流量计费的?


这是Windows 8吗?我认为Windows 8有一个“计量”属性,你可以在连接上设置,但我在7或更早的版本中没有看到它。 - Rup
2
如果考虑到任意网络连接,我觉得这个可能做不到,如果真的能做到,我会非常惊讶。 - Matt Ball
1
@Rup:这不是Windows业务。它与ISP联系并询问链接类型。 - Xaqron
2
我从没想过这会这么复杂。在 Windows 8 中,您可以手动指定连接为计量的。那个标志一定存储在某个地方,并且通过 API 或者直接读取注册表进行读取。我不打算构建使用启发式或者其他什么,只是想读取手动设置。 - Joshua Frank
Windows 8.1连接手机时似乎会自动检测此项。Outlook因此显示将脱机工作。 - Anon343224user
显示剩余4条评论
2个回答

6

在MSDN上进行简要搜索,找到了NetworkInformation.GetInternetConnectionProfile函数。它似乎是Metro界面的正式部分,但我听说桌面应用程序可以访问大多数Metro库。


1
在2021年,您可以使用PowerShell .NET框架和类似的注册表KEY来测试以太网连接是否设置为按流量计费:
$definition = @"
using System;
using System.Runtime.InteropServices;

namespace Win32Api
{

    public class NtDll
    {
        [DllImport("ntdll.dll", EntryPoint="RtlAdjustPrivilege")]
        public static extern int RtlAdjustPrivilege(ulong Privilege, bool Enable, bool CurrentThread, ref bool Enabled);
    }
}
"@

Add-Type -TypeDefinition $definition -PassThru | Out-Null
[Win32Api.NtDll]::RtlAdjustPrivilege(9, $true, $false, [ref]$false) | Out-Null

#Setting ownership to Administrators
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::takeownership)
$acl = $key.GetAccessControl()
# Use your account "Administrators" or any other which is actually an existing one on your account
$acl.SetOwner([System.Security.Principal.NTAccount]"Administrators")
$key.SetAccessControl($acl)

#Giving Administrators full control to the key
$rule = New-Object System.Security.AccessControl.RegistryAccessRule ([System.Security.Principal.NTAccount]"Administrators","FullControl","Allow")
$acl.SetAccessRule($rule)
$key.SetAccessControl($acl)
$path = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost"
# you can check for "Ethernet" "Wifi" "4G" etc.
$name = "Ethernet"
#If the Value is 2 = metered
New-ItemProperty -Path $path -Name $name -Value "2" -PropertyType DWORD -Force | Out-Null

如果你遇到以下错误:
Exception calling "SetAccessRule" with "1" argument(s): "Some or all identity references could not be translated.".

尝试将“管理员”用户更改为任何其他已存在且具有管理权限的用户。

恭喜你找到了解决方案,但我不喜欢改变注册表权限的想法。一定有其他方法可以找到这个问题的解决方案。 - Rup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接