сделать программу, чтобы верить, работает на домене, объединенной машиной [duplicate]

Если у вас есть такой массив

  data = array ([0] = & gt; array ([subject] = & gt; a [object] = & gt; c), [1  ] = & gt; array ([subject] = & gt; b [object] = & gt; d), [2] = & gt; array ([subject] = & gt; d [object] = & gt; b), [3] =  & gt; массив ([subject] = & gt; d [object] = & gt; c), [4] = & gt; array ([subject] = & gt; c [object] = & gt; a), [5] = & gt;  array [[subject] = & gt; c [object] = & gt; d))  

, и вы хотите получить такие массивы:

  data =  array ([0] = & gt; array ([subject] = & gt; a [object] = & gt; c), [1] = & gt; array ([subject] = & gt; b [object] = & gt; d),  [2] = & gt; array ([subject] = & gt; d [object] = & gt; c))  

или

  data = array (  [0] = & gt; array ([subject] = & gt; d [object] = & gt; b), [1] = & gt; array ([subject] = & gt; c [object] = & gt; a), [2  ] = & gt; ([subject] = & gt; c [object] = & gt; d))  

следующий код может помочь

  $ data1  = array ();  $ data1 = $ data;  for ($ q = 0; $ q & lt; count ($ data); $ q ++) {for ($ p = 0; $ p & lt; count ($ data1); $ p ++) {if (($ data [$ q] [  "subject"] == $ data1 [$ p] ["object"]) & amp; & amp; ($ data [$ q] ["object"] == $ data1 [$ p] ["subject"])) {  $ data1 [$ p] ["subject"] = $ data [$ q] ["subject"];  $ data1 [$ p] ["object"] = $ data [$ q] ["object"];  }}} $ data1 = array_values ​​(array_map ("unserialize", array_unique (array_map ("serialize", $ data1))));  $ data = $ data1;   
48
задан DSO 29 May 2009 в 15:20
поделиться

12 ответов

Вы можете использовать PInvoke для API Win32, например NetGetDcName , который вернет пустую / пустую строку для машины, не связанной с доменом.

Еще лучше NetGetJoinInformation [ ! d1], который явно укажет вам, если машина не установлена, в рабочей группе или в домене.

Используя NetGetJoinInformation Я собрал это, что сработало для меня:

  public class Test {public static bool IsInDomain () {Win32.NetJoinStatus status = Win32.NetJoinStatus.NetSetupUnknownStatus;  IntPtr pDomain = IntPtr.Zero;  int result = Win32.NetGetJoinInformation (null, out pDomain, out status);  if (pDomain! = IntPtr.Zero) {Win32.NetApiBufferFree (pDomain);  } if (result == Win32.ErrorSuccess) {return status == Win32.NetJoinStatus.NetSetupDomainName;  } else {throw new Exception («Ошибка получения информации о домене», новый Win32Exception ());  }}} внутренний класс Win32 {public const int ErrorSuccess = 0;  [DllImport («Netapi32.dll», CharSet = CharSet.Unicode, SetLastError = true)] public static extern int NetGetJoinInformation (строковый сервер, вне домена IntPtr, статус NetJoinStatus);  [DllImport («Netapi32.dll»)] public static extern int NetApiBufferFree (IntPtr Buffer);  public enum NetJoinStatus {NetSetupUnknownStatus = 0, NetSetupUnjoined, NetSetupWorkgroupName, NetSetupDomainName}}  
25
ответ дан Filip Navara 16 August 2018 в 02:39
поделиться
  • 1
    Круто. Но нет ли утечки памяти в вашей функции, данные pDomain, возвращаемые NetGetJoinInformation? – DSO 29 May 2009 в 15:55
  • 2
    (не то, что утечка слишком важна ... поскольку я буду называть это один раз и кэшировать ее) – DSO 29 May 2009 в 15:57
  • 3
    Ahh - образец кода, который я взломал с сайта PInvoke, вызывал NetApiBufferFree - я добавил это к образцу =) – Rob 29 May 2009 в 16:10
  • 4
    Важно отметить, что NetGetJoinInformation возвращает устаревшее доменное имя NetBIOS, а не имя домена (следовательно, Net в NetGetJoinInformation) – Ian Boyd 20 March 2012 в 19:48
  • 5
    Вместо выкинуть новое исключение («Доменная информация Get Failed»); вы должны сделать throw new Exception («Ошибка получения информации о домене»), новый Win32Exception ()); insetad. Внутренний Win32Exception будет внутренне вызывать Marshal.GetLastWin32Error () и установить код ошибки и сообщение об ошибке для этого кода во внутреннем исключении. Вот почему вы делаете SetLastError = true в подписи p / invoke, так что Marshal.GetLastWin32Error () будет работать. – Scott Chamberlain 17 February 2017 в 22:06

Предлагаемое решение выше возвращает false на машине домена, если локальный пользователь зарегистрирован.

Самый надежный метод, который я нашел, - через WMI:

http : //msdn.microsoft.com/en-us/library/aa394102 (v = vs.85) .aspx (см. domainrole)

0
ответ дан Andrew Morgan 16 August 2018 в 02:39
поделиться

Если производительность имеет значение, используйте функцию GetComputerNameEx :

  bool IsComputerInDomain () {uint domainNameCapacity = 512;  var domainName = new StringBuilder ((int) domainNameCapacity);  GetComputerNameEx (COMPUTER_NAME_FORMAT.ComputerNameDnsDomain, domainName, ref domainNameCapacity);  return domainName.Length & gt;  0;  } [DllImport ("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern bool GetComputerNameEx (COMPUTER_NAME_FORMAT NameType, StringBuilder lpBuffer, ref uint lpnSize);  enum COMPUTER_NAME_FORMAT {ComputerNameNetBIOS, ComputerNameDnsHostname, ComputerNameDnsDomain, ComputerNameDnsFullyQualified, ComputerNamePhysicalNetBIOS, ComputerNamePhysicalDnsHostname, ComputerNamePhysicalDnsDomain, ComputerNamePhysicalDnsFullyQualified}  
1
ответ дан Artem 16 August 2018 в 02:39
поделиться

Переменные среды могут работать для вас.

  Environment.UserDomainName  

Ссылка MSDN для получения более подробной информации. [ ! d5]

  Environment.GetEnvironmentVariable ("USERDNSDOMAIN")  

Я не уверен, что эта переменная среды существует, не находясь в домене.

Исправьте меня, если я ошибаюсь. Гитаристы Windows Admin - я считаю, что компьютер может быть в нескольких доменах, поэтому может быть более важно знать, в каком домене вы находитесь, а не в , любом домен.

3
ответ дан Austin Salonen 16 August 2018 в 02:39
поделиться
  • 1
    Насколько мне известно, компьютер может быть присоединен только к домену one , но вы можете войти в систему на компьютере, используя учетные данные из более чем одного домена в этом лесу или из нескольких лесов, если есть трасты. Все это становится слишком сложным, хотя =) – Rob 29 May 2009 в 16:17
  • 2
    Environment.UserDomainName возвращает имя компьютера, если машина не присоединена к домену. Я полагаю, что могу сравнить это с Environment.MachineName, чтобы определить, присоединился ли его домен, но я не уверен, что это будет правильно во всех ситуациях. – DSO 29 May 2009 в 17:26
  • 3
    @DSO - Я знаю, что я здесь поздно, но на всякий случай кто-то наткнулся на этот поток, я просто хотел упомянуть, что даже на машине, подключенной к домену, если учетная запись пользователя, на которой запущен процесс, является локальной учетной записью или системной учетной записью , вы не можете полагаться на UserDomainName! = MachineName. – Josh 11 May 2010 в 20:52
  • 4
    @DSO, это будет. Домены и машины имеют пространство имен. – Joshua 5 December 2011 в 18:32
  • 5
    @ blak3r. Поскольку процесс, выполняемый как локальный пользователь на машине, подключенной к домену, возвращает имя машины, а не имя домена, так же, как если бы он не был присоединен к домену. Было предложено использовать это как указание присоединенного домена или нет. – Josh 2 October 2012 в 15:10

Вот мои методы с обработкой / комментариями исключений, которые я разработал на основе нескольких ответов в этом сообщении.

  1. Получает домен, к которому подключен компьютер.
  2. Возвращает только имя домена, если пользователь действительно зарегистрирован в учетной записи домена. /// & lt; summary & gt; /// Возвращает домен зарегистрированного пользователя. /// Поэтому, если компьютер подключен к домену, но пользователь входит в локальную учетную запись. String.Empty будет возвращен. /// Relavant StackOverflow Post: http://stackoverflow.com/questions/926227/how-to-detect-if-machine-is-joined-to-domain-in-c /// & lt; / summary & gt; /// & lt; seealso cref = "GetComputerDomainName" / & gt; /// & lt; возвращает & gt; Доменное имя, если пользователь подключен к домену, String.Empty, если нет. & lt; / returns & gt; static string GetUserDomainName () {строка domain = String.Empty; try {domain = Environment.UserDomainName; string machineName = Environment.MachineName; if (machineName.Equals (домен, StringComparison.OrdinalIgnoreCase)) {domain = String.Empty; }} catch {// обрабатывать исключение, если требуется, в противном случае возвращает null} return domain; } /// & lt; summary & gt; /// Возвращает домен, к которому подключен компьютер. Примечание: если пользователь зарегистрирован как локальная учетная запись, домен компьютера все еще возвращается! /// & lt; / summary & gt; /// & lt; seealso cref = "GetUserDomainName" / & gt; /// & lt; returns & gt; Строка с именем домена, если она соединена. String.Empty, если это не так. & Lt; / returns & gt; static string GetComputerDomainName () {строка domain = String.Empty; try {domain = System.DirectoryServices.ActiveDirectory.Domain.GetComputerDomain (). Имя; } catch {// При необходимости обработать исключение. } return domain; }
2
ответ дан blak3r 16 August 2018 в 02:39
поделиться

Может также вызываться с помощью system.net

  string domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties (). DomainName  

Если строка домена пуста, машина не связана.

13
ответ дан Eric Herlitz 16 August 2018 в 02:39
поделиться
  • 1
    Это лучший ответ, поскольку это и управляемое решение, и самое быстрое. – David Bentley 15 May 2018 в 14:20

Не обманывайте pinvoke, если вам это не нужно.

Reference System.DirectoryServices, а затем вызывается:

  System.DirectoryServices.ActiveDirectory.Domain.  GetComputerDomain ()  

Выбрасывает ActiveDirectoryObjectNotFoundException , если машина не подключена к домену. Возвращаемый объект Domain содержит свойство Name, которое вы ищете.

85
ответ дан Helge Klein 16 August 2018 в 02:39
поделиться
  • 1
    Мне всегда нравится находить, что существует управляемая версия почти чего угодно. – Ignacio Soler Garcia 15 September 2010 в 14:23
  • 2
    Обратите внимание на другие. [D0] убедитесь, что вы используете GetComputerDomain () (как было предложено выше) и не GetCurrentDomain () . GetCurrentDomain () для возрастов, если вы не подключены к домену. – James 9 July 2011 в 15:57
  • 3
    Существует проблема с этим вызовом, поскольку для многих конфигураций требуется около 2 минут. – Ivan G. 8 September 2011 в 11:42
  • 4
    Следуя моим предыдущим, я использовал LINQPad и использовал Dump () на объекте Domain, что и занимало так много времени! Просто доступ к свойству Name возвращаемого экземпляра домена происходит очень быстро. :-) – Norman H 29 September 2011 в 15:12
  • 5
    Это решение не работает, если вам нужно знать, подключен ли компьютер к домену, даже если он в настоящее время не подключен к сети. В этом случае он будет вызывать исключение ActiveDirectoryObjectNotFoundException. – Preston McCormick 21 November 2012 в 01:42

Возможно, вы захотите попробовать использовать поле DomainRole WMI. Значения 0 и 2 показывают автономную рабочую станцию ​​и автономный сервер соответственно.

Мы используем это для XIA Configuration для нашего программного обеспечения для сетевого аудита, поэтому я тут же подкрепил метод ...

  /// & lt; summary & gt;  /// Определяет, является ли локальная машина членом домена.  /// & lt; / summary & gt;  /// & lt; возвращает & gt; Булево значение, указывающее, является ли локальная машина членом домена. & lt; / returns & gt;  /// & lt; примечания & gt; http: //msdn.microsoft.com/en-gb/library/windows/desktop/aa394102 (v = vs.85) .aspx & lt; / remarks & gt;  public bool IsDomainMember () {ManagementObject ComputerSystem;  using (ComputerSystem = new ManagementObject (String.Format ("Win32_ComputerSystem.Name = '{0}'", Environment.MachineName))) {ComputerSystem.Get ();  UInt16 DomainRole = (UInt16) ComputerSystem ["DomainRole"];  return (DomainRole! = 0 & amp; DomainRole! = 2);  }}  
1
ответ дан Martijn Pieters 16 August 2018 в 02:39
поделиться

Вы можете проверить с помощью WMI:

  private bool PartOfDomain () {ManagementObject manObject = new ManagementObject (string.Format ("Win32_ComputerSystem.Name = '{0}'", Environment.MachineName  ));  return (bool) manObject ["PartOfDomain"];  }  
1
ответ дан Me Hungry 16 August 2018 в 02:39
поделиться

Вы можете проверить свойство PartOfDomain класса WMI Win32_ComputerSystem. [D0] MSDN говорит:

PartOfDomain

Тип данных: boolean

Тип доступа: только для чтения

Если True, компьютер является частью домена. Если значение NULL, компьютер не находится в домене или статус неизвестен. Если вы отсоедините компьютер от домена, значение станет false.

  /// & lt; summary & gt;  /// Определяет, является ли локальная машина членом домена.  /// & lt; / summary & gt;  /// & lt; возвращает & gt; Булево значение, указывающее, является ли локальная машина членом домена. & lt; / returns & gt;  /// & lt; примечания & gt; http: //msdn.microsoft.com/en-us/library/windows/desktop/aa394102%28v=vs.85%29.aspx< / замечания & gt;  public bool IsDomainMember () {ManagementObject ComputerSystem;  using (ComputerSystem = new ManagementObject (String.Format ("Win32_ComputerSystem.Name = '{0}'", Environment.MachineName))) {ComputerSystem.Get ();  object Result = ComputerSystem ["PartOfDomain"];  return (Результат! = null & amp; & amp; (bool) Результат);  }}  
3
ответ дан neilbgr 16 August 2018 в 02:39
поделиться

Просто хотел отбросить код Роба в VB:

  Открытый класс Test Public Function IsInDomain () As Boolean Попробовать состояние Dim Как Win32.NetJoinStatus = Win32.NetJoinStatus.NetSetupUnknownStatus Dim pDomain As IntPtr =  IntPtr.Zero Dim result As Integer = Win32.NetGetJoinInformation (Nothing, pDomain, status) Если (pDomain & lt; gt; IntPtr.Zero) Затем Win32.NetApiBufferFree (pDomain) End If If (result = Win32.ErrorSuccess) Затем If (status  = Win32.NetJoinStatus.NetSetupDomainName) Затем верните True Else Return False End If Else Throw New Exception («Ошибка получения информации о домене») End If Catch ex As Exception Return False End Try End Function End Class Открытый класс Win32 Public Const ErrorSuccess As Integer =  0 Объявить автоматическую функцию NetGetJoinInformation Lib «Netapi32.dll» (ByVal server As String, ByRef IntPtr As IntPtr, ByRef status As NetJoinStatus) Как целое объявляет автоматическую функцию NetApiBufferFree Lib «Netapi32.dll» (ByVal Buffer As IntPtr) Как Integer Public Enum NetJoinStatus  NetSetupUnknownStatus  = 0 NetSetupUnjoined NetSetupWorkgroupName NetSetupDomainName End Enum End Class  

Также как и код Стефана здесь:

  Dim cs As System.Management.ManagementObject Попробуйте cs = Новая система  .Management.ManagementObject ("Win32_ComputerSystem.Name = '" + System.Environment.MachineName + "'") cs.Get () dim myDomain как string = = cs ("domain"). ToString Catch ex As Exception End Try  

Я считаю, что только второй код позволит вам узнать, к какой области присоединился компьютер, даже если текущий пользователь НЕ является членом домена.

5
ответ дан PatTheFrog 16 August 2018 в 02:39
поделиться
  ManagementObject cs;  using (cs = new ManagementObject ("Win32_ComputerSystem.Name = '" + System.Environment.MachineName + "'")) {cs.Get ();  Console.WriteLine ( "{0}", CS [ "домен"] ToString ());  }  

Это должно позволить вам получить домен. Я полагаю, что это будет пустой или пустой, если вы являетесь частью рабочей группы, а не домена.

Обязательно обратитесь к System.Management

6
ответ дан Stephan 16 August 2018 в 02:39
поделиться
  • 1
    Он возвращает «WORKGROUP». если не в домене. Это будет работать (если вы не находитесь в домене с именем «WORKGROUP»), но я подожду немного, чтобы увидеть, существует ли подход, основанный на не-WMI, прежде чем выбрать его в качестве правильного ответа. – DSO 29 May 2009 в 15:38
  • 2
    Спасибо, что дали мне знать. У меня есть только моя рабочая машина для тестирования, и я не могу точно удалить ее из домена для тестирования. – Stephan 29 May 2009 в 15:41
  • 3
    С другой стороны, я не думаю, что это сработает. Оказывается, имя рабочей группы для моего тестового окна на самом деле WORKGROUP. Я думаю, что его возвращение названия рабочей группы, а не фиксированное значение, которое с точки зрения API имеет больше смысла, но это означает, что вы не можете использовать это, чтобы определить, присоединился ли его домен. – DSO 29 May 2009 в 17:31
  • 4
    +1 для метода выполняется быстро, не требует входа пользователя в систему или даже требует доступа к DC для получения имени – Mhmd 11 November 2014 в 22:19
Другие вопросы по тегам:

Похожие вопросы: