开发者

Unable to use IIS ADSI Provider after IIS installation if ADsOpenObject was called before install

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜