所以我已经非常了解如何使用INetFwPolicy2
和INetFwRule
COM接口以编程方式设置防火墙规则。但是,如何使用COM interop为特定的“Modern App”/“Metro App”/“Store App”设置规则?
如果我使用防火墙MMC,我可以去:
规则 - >属性 - >计划和服务 - >应用程序包
并允许/阻止指定的包。但我不知道如何在代码中执行此操作。我找到了提供INetFwRule3
属性的LocalAppPackageId
接口,这就是我认为所有的魔力。但是LocalAppPackageId
包含包的SID,而不是像microsoft.windows.photos_8wekyb3d8bbwe
这样的名称。那么,当我所知道的是它的名字时,我怎么能阻止我想要的包裹呢?我想我必须得到SID,所以我该如何找到它? SID的范围是本地的(每台机器是唯一的),或者我可以在找到SID后对其进行硬编码,而不是动态查找SID吗?
答案 0 :(得分:1)
可以使用NetworkIsolationEnumAppContainers
和ConvertSidToStringSid
API找到应用容器的SID。这是他们Fiddler does中的AppContainer Loopback Exemption Utility(这就是我找到API的方式)。
如果您只关心SID而不关心其他任何事情,那么使用DeriveAppContainerSidFromAppContainerName
/ ConvertSidToStringSid
组合会更容易。您甚至不必使用ConvertSidToStringSid
,.NET框架已经提供了转换:
private static string SidToString(IntPtr sid)
{
return new SecurityIdentifier(sid).Value;
}
奇怪的是,DeriveAppContainerSidFromAppContainerName
没有检查系统上是否存在应用程序容器,它似乎只是接受你抛出的任何输入并仅从该信息生成SID(如散列函数)。
完整的代码:
public static string AppContainerNameToSid(string appContainerName)
{
var sid = IntPtr.Zero;
try
{
if (DeriveAppContainerSidFromAppContainerName(appContainerName, out sid) == 0)
return new SecurityIdentifier(sid).Value;
else
return null;
}
finally
{
if (sid != IntPtr.Zero)
FreeSid(sid);
}
}
[DllImport("userenv.dll", SetLastError = false, CharSet = CharSet.Unicode)]
private static extern int DeriveAppContainerSidFromAppContainerName(string appContainerName, out IntPtr sid);
[DllImport("advapi32.dll", SetLastError = false)]
private static extern IntPtr FreeSid(IntPtr sid);