My .Net application actively uses Active Directory and installs IIS if its absent. If IIS wasn't installed on application startup and any of Active Directory-related methods were called then IIS ADSI Provider stills unavailable after IIS installation (after application restart it becomes available).
Unfortunately i cannot change the operations sequence, so it must be "use AD -> install IIS -> use IIS ADSI provider -> use AD"My steps-to-reproduce code (not real) is:
using (Domain domain = Domain.GetCurrentDomain())
{
}
// IIS install here
using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1"))
{
var options = entry.Options; // exception here
}
Changed sequence works fine:
// IIS install here
using (Domain domain = Domain.GetCurrentDomain())
{
}
using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1"))
{
var options = entry.Options;
}
Using Reflector i have found that it is enough to call ADsOpenObject once to make IIS ADSI provider unavailable after IIS installation.
class Program
{
static void Main(string[] args)
{
object ldapPPObject = GetAdsObject("LDAP://TestDomain.local/RootDSE");
Marshal.R开发者_JS百科eleaseComObject(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);
}
I have tried to create separate app domain and place there code that uses IIS but this try was failed too.
How can i force AD reinitialization to get IIS ADSI provider available after IIS installation?
.Net had nothing to do with the problem.
The following c++ code fails too:
int _tmain(int argc, _TCHAR* argv[])
{
IADs *pObject;
HRESULT hr;
CoInitialize(NULL);
hr = ADsOpenObject(L"LDAP://TestDomain.local/RootDSE", NULL, NULL, 193, IID_IADs, (void**) &pObject);
if(SUCCEEDED(hr))
{
pObject->Release();
}
// install iis here
hr = ADsOpenObject(L"IIS://localhost/W3SVC/1", NULL, NULL, 193, IID_IADs, (void**) &pObject);
if(SUCCEEDED(hr)) // not succeeded
{
pObject->Release();
}
CoUninitialize();
return 0;
}
But the trouble still need to be solved somehow...
There is no way to get the ADSI provider working again after the call to ADsOpenObject. Sorry.
精彩评论