【发布时间】:2010-01-04 16:45:42
【问题描述】:
我的 .Net 应用程序主动使用 Active Directory 并在没有 IIS 时安装它。
如果在应用程序启动时未安装 IIS,并且调用了任何与 Active Directory 相关的方法,则 IIS ADSI 提供程序在 IIS 安装后仍然不可用(应用程序重新启动后它变得可用)。
不幸的是我不能改变操作顺序,所以它必须是“use AD -> install IIS -> use IIS ADSI provider -> use AD”
我的重现代码的步骤(不是真实的)是:
using (Domain domain = Domain.GetCurrentDomain())
{
}
// IIS install here
using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1"))
{
var options = entry.Options; // exception here
}
更改后的顺序可以正常工作:
// IIS install here
using (Domain domain = Domain.GetCurrentDomain())
{
}
using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1"))
{
var options = entry.Options;
}
使用 Reflector 我发现只要调用一次ADsOpenObject 就足以使 IIS ADSI 提供程序在 IIS 安装后不可用。
class Program
{
static void Main(string[] args)
{
object ldapPPObject = GetAdsObject("LDAP://TestDomain.local/RootDSE");
Marshal.ReleaseComObject(ldapPPObject);
// IIS install here
object iisPPObject = GetAdsObject("IIS://localhost/W3SVC/1"); // exception here
Marshal.ReleaseComObject(iisPPObject);
}
private static object GetAdsObject(string path)
{
Guid iid = new Guid("00000000-0000-0000-c000-000000000046");
object ppObject;
if (IntADsOpenObject(path, null, null, 193, ref iid, out ppObject) != 0)
{
throw new Exception("ADsOpenObject failed");
}
return ppObject;
}
[DllImport("activeds.dll", EntryPoint = "ADsOpenObject", CharSet = CharSet.Unicode, ExactSpelling = true)]
private static extern int IntADsOpenObject(string path, string userName, string password, int flags, [In, Out] ref Guid iid, [MarshalAs(UnmanagedType.Interface)] out object ppObject);
}
我曾尝试创建单独的应用程序域并在其中放置使用 IIS 的代码,但此尝试也失败了。
如何在 IIS 安装后强制 AD 重新初始化以使 IIS ADSI 提供程序可用?
【问题讨论】: