Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Refresh DirectoryServices cache, Есть ли возможность обновить кэш DS? 
V
    Опции темы
mihryak
Дата 2.1.2010, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



С Новым Годом, коллеги!

В приложении необходимо устанавливать IIS (шестой, но это роли не играет), чтобы затем, используя Active Directory, довести его до рабочего состояния. При этом, в том же приложении также активно используется AD, причём, как до установки IIS'а, так и после.
Теперь к сути проблемы:
настройка IIS'a в общих чертах заключается в получении DirectoryEntry нужного сайта и некоторых операциях с ним, для простоты можно ограничиться лишь получением:
Код

            using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1")) // здесь может быть и IIS://localhost/W3SVC, и IIS://localhost, и просто IIS:
            {
                var options = entry.Options;
            }

но вся штука заключается в том, что до этого вызова я уже обращался к AD, к примеру, так:
Код

            using (Domain domain = Domain.GetCurrentDomain())
            {                
            }

этот код, по всей видимости, поднимает, инициализирует и кэширует всех имеющихся на момент инициализации поставщиков данных (LDAP, IIS, etc.), но IIS'а на момент этой инициализации ещё нет в системе, и первый код получения сайта благополучно вываливается с типичным COM-исключением на любом свойстве-методе DirectoryEntry, как будто её не удалось найти

т.е. так не работает
Код

            using (Domain domain = Domain.GetCurrentDomain())
            {
            }

            // IIS install

            using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1"))
            {
                var options = entry.Options;
            }

, а так работает
Код

            // IIS install

            using (Domain domain = Domain.GetCurrentDomain())
            {
            }

            using (DirectoryEntry entry = new DirectoryEntry("IIS://localhost/W3SVC/1"))
            {
                var options = entry.Options;
            }

И не важно, программно ли ставится IIS, или через компоненты системы, всё равно ошибка одна и та же, при этом второе такое же приложение, запущенное уже после установки, работает на ура
Т.е. проблема именно в кэшировании.
И, собственно, вопрос: можно ли как-нибудь принудительно переинициализировать кэш или всю сборку System.DirectoryServices?
У DirectoryEntry есть метод RefreshCache(), но он, собака такая, работает только с живой Entry, а у меня она уже мертворождённая.
Пробовал вынести получение и работу с сайтом в отдельный AppDomain, надеясь, что там будет заново проходить поднятие AD, но результат тот же.
Ещё пробовал найти рефлектором эту инициализацию в сборке - не нашёл, но ведь она где-то там должна быть..
Ну и последней надеждой было воспользоваться исходниками фреймворка, любезно предоставленными MS, но DirectoryServices, увы, не вошла в представленный список.

Может какие-нибудь свежие идеи найдутся?

 smile 

Это сообщение отредактировал(а) mihryak - 2.1.2010, 23:23
PM MAIL ICQ   Вверх
mihryak
Дата 4.1.2010, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



всё оказалось на порядок унылее, чем я надеялся
поковырявшись в рефлекторе, удалось редуцировать код до такого:
Код

    class Program
    {
        static void Main(string[] args)
        {
            object ldapPPObject = GetAdsObject("LDAP://TestDomain.local/RootDSE");
            Marshal.ReleaseComObject(ldapPPObject);

            // install iis here

            object iisPPObject = GetAdsObject("IIS://localhost/W3SVC/1");
            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);
    }


как и прежде, после рестарта приложения всё работает

т.е. проблема кэширования находится не во фреймворке, а в unmanaged коде - если этот интеропный метод вызывался до установкии ииса, то его провайдер до конца жизни приложения будет недоступен

мсдн пишет, что этот метод - обёртка над комовым объектом, может, это как-то поможет решить мерзопакостную проблему?

Это сообщение отредактировал(а) mihryak - 4.1.2010, 00:38
PM MAIL ICQ   Вверх
mihryak
Дата 6.1.2010, 00:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



последние известия
Код

#include "stdafx.h"

#include <atlbase.h>
#include <Iads.h>
#include <Adshlp.h>

#pragma comment(lib, "Activeds.lib")
#pragma comment(lib, "Adsiid.lib")

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();
    }

    hr = ADsOpenObject(L"IIS://localhost/W3SVC/1", NULL, NULL, 193, IID_IADs, (void**) &pObject);

    if(SUCCEEDED(hr))
    {
        pObject->Release();
    }

    CoUninitialize();

    return 0;
}

точно так же не работает
дот.нет реабилитирован, тему помечаю закрытой  smile 

создал топик в плюсовом разделе (осторожно, рекурсия!  smile )

Это сообщение отредактировал(а) mihryak - 6.1.2010, 01:41
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0410 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.