Я некоторое время гуглил эту проблему и не смог найти никого, кто бы испытывал такие же проблемы. У меня есть приложение, написанное на C #, которое делает много вещей, необходимых нашей IT HelpDesk. Все отлично работает (включая перезагрузку NT PW и множество удаленных установок), кроме той части, которая отображает информацию о пользователе Active Directory. У меня есть всплывающее окно, в котором будет отображаться информация об обмене, статус блокировки, членство в группах и многое другое.
Приложение устанавливается и обновляется через ClickOnce и разработано для .NET Framework 3.5 (проверено установлено на всех компьютерах). Когда пользователь нажимает кнопку, чтобы отобразить информацию о пользователе, ему предлагается указать домен и имя пользователя. Затем программа ищет пользователя и отображает результаты поиска, если имя пользователя не совсем правильно. После того, как пользователь выбирает имя пользователя, которое он хочет, происходит одно из двух:
Примерно в 4 из 5 раз он работает как задумано и отображает нужную информацию
Вся программа блокируется и требует принудительного завершения.
Я не до конца понимаю, почему он блокируется, поскольку вся работа, выполняемая после первого нажатия кнопки (перед запросом домена и имени пользователя), выполняется в отдельном потоке. Я думаю, что это предотвратит блокировку основного потока, если это вызвано какой-либо ошибкой. Единственная разница между этой функцией и некоторыми другими функциями AD, которая не дает сбоя, заключается в том, что эта функция использует расширение ActiveDs.dll, поэтому я думаю, что это может быть связано с этим. Я могу также при необходимости отправить код.
Это код, который запускает окно AD в новом потоке
private void ADInfoB_Click(object sender, RoutedEventArgs e)
{
string domain = Interaction.InputBox("Domain Name", "Please Enter the domain the user is on");
if (domain != "")
{
string usern = Interaction.InputBox("User Name", "Please enter the NT user name of the user");
if (usern != "")
{
try
{
string userDN = ActiveDirectory.DistinguishedUserName(usern, domain);
if (userDN != null)
{
Thread userInfoT = new Thread(() =>
{
ADWindow ADInfo = new ADWindow();
ADInfo.Show();
ADInfo.ADStartupInfo(usern, domain, userDN);
ADInfo.Closed += (sender2, e2) =>
ADInfo.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
userInfoT.SetApartmentState(ApartmentState.STA);
userInfoT.Start();
}
}
catch (Exception a)
{
MessageBox.Show(a.ToString());
}
}
}
}
Вызов «ActiveDirectory.DistinguishedUserName (usern, domain);» выглядит так:
public static string DistinguishedUserName(string user, string LDAPDomain)
{
try
{
threadParams param = new threadParams();
param.usern = user;
param.domain = LDAPDomain;
string distName = string.Empty;
Thread userDistName = new Thread(() =>
{
DSWindow DNuser = new DSWindow();
DNuser.Show();
DNuser.setupUserDN(param);
DNuser.Closed += (sender2, e2) =>
DNuser.Dispatcher.InvokeShutdown();
System.Windows.Threading.Dispatcher.Run();
});
userDistName.SetApartmentState(ApartmentState.STA);
userDistName.Start();
while (userDistName.IsAlive)
{
System.Threading.Thread.Sleep(1000);
}
distName = param.userDN;
return distName;
}
catch (Exception e)
{
MessageBox.Show("" + e);
return "Fail";
}
}
и фактический поиск:
public void DistNameUser(object a)
{
threadParams param = a as threadParams;
string usern = param.usern;
string LDAPDomain = param.domain;
string userDN = string.Empty;
string connectionPrefix = "LDAP://" + LDAPDomain;
DirectoryEntry entry = new DirectoryEntry(connectionPrefix);
DirectorySearcher mySearcher = new DirectorySearcher(entry);
UpdateListDelegate ListDelegate = new UpdateListDelegate(UpdateList);
GetIndexDelegate IndexDelegate = new GetIndexDelegate(getIndex);
CloseWindowDelegate cw = new CloseWindowDelegate(closeWindow);
mySearcher.Filter = "(&(objectClass=user)(|(sAMAccountName=" + usern + "*)))";
SearchResultCollection results = mySearcher.FindAll();
foreach (SearchResult res in results)
{
DirectoryEntry tempEnt = res.GetDirectoryEntry();
string strRes = tempEnt.Properties["sAMAccountName"].Value as string;
Dispatcher.Invoke(ListDelegate,
System.Windows.Threading.DispatcherPriority.Background,
new object[] { strRes });
}
SelectionMade.WaitOne();
Dispatcher.Invoke(IndexDelegate,
System.Windows.Threading.DispatcherPriority.Background,
new object[] { param });
SearchResult picked = results[param.index];
DirectoryEntry directoryObject = picked.GetDirectoryEntry();
userDN = "LDAP://" + directoryObject.Properties["distinguishedName"].Value;
param.userDN = userDN;
entry.Close();
entry.Dispose();
mySearcher.Dispose();
Dispatcher.Invoke(cw,
System.Windows.Threading.DispatcherPriority.Background,
new object[] { });
}
Дайте мне знать, если вы хотите увидеть больше код