2009-09-16 3 views
0

Мы работаем над веб-службой, которая должна запускать сторонний процесс, который взаимодействует с подключенным сетевым диском. Поэтому мы должны программно отобразить этот диск из веб-службы.C# - Карта сетевого диска с веб-службы

Я уже завернутые WNetAddConnection2 и т.д. в более удобном классе для другого проекта, поэтому я бросил код прямо.

Наш веб-сервис работает под UltiDev Кассини (вместо IIS), который работает под Системная учетная запись. Мы получаем код ошибки для: «указанное имя устройства недействительно» каждый раз. Я также пытался выдавать себя за других пользователей в файле web.config с теми же результатами.

Привод будет отображаться очень хорошо, когда я запускаю свой код из консоли при обычной учетной записи пользователя.

Я также пробовал использовать эквивалентную команду «net use» из C# с теми же результатами, что и WNetAddConnection.

Кто-нибудь знает, почему служба Windows или пользователь системы не смогут сопоставить сетевые диски?

Кто-нибудь знает обходное решение? Простое сопоставление накопителя при запуске системы было бы решением, но как может пользователь системы/имперсонального доступа получить к нему доступ?

Ссылка для UltiDev Кассини: UltiDev

РЕШЕНИЕ: Я установил службу UltiDev Кассини для входа в систему под администратором и все работает. Выдача ASP.NET не должна работать так, как планировалось.

ответ

2

LOCAL_SYSTEM аккаунт анонимный credentials on the network. Вы можете использовать общий сетевой ресурс UNC для доступа к этой информации, при условии, что анонимный (Everyone) имеет доступ к этому ресурсу.

Вы также можете использовать install Cassini as a windows service, который можно настроить для работы под другим пользователем.

2

Если вы используете учетную запись локальной системы, то я считаю, что она по своей сути неспособна получить доступ к сети [foo]. Я бы сказал, что олицетворение - это ваш единственный жизнеспособный путь. Технически вы можете ограничить контроль доступа на общем ресурсе до такой степени, что каждый может читать/записывать в общий ресурс, но это создает больше проблем, чем решения.

+0

Тогда почему же олицетворение web.config не работает? Я напечатал имя Environment.Username в нашем журнале, и он печатает администратор, но если я посмотрю на процесс UltiDev - он все еще находится в локальной системе. Может ли UltiDev делать что-то странное? – jonathanpeppers

+1

У учетной записи Local System есть доступ к сети, но она предоставляет анонимные учетные данные сетевым ресурсам. – bryanbcook

1

У нас была та же проблема. Проблема возникает из-за учетной записи, в которой работает код. Вы можете обойти это, как мы это сделали, используя следующий класс. Вам необходимо сопоставить диск в том же коде, который вы используете для доступа/копирования файлов. Мы используем шаблон, чтобы всегда проверять, подключен ли первый диск. если это так, мы отключим его, а затем снова подключим его. если нет, мы просто подключаем его. Похоже, что он проясняет проблему, которую вы описываете.

public static class NetworkDrives 
    { 
     public static bool MapDrive(string DriveLetter, string Path, string Username, string Password) 
     { 

      bool ReturnValue = false; 

      if(System.IO.Directory.Exists(DriveLetter + ":\\")) 
      { 
       DisconnectDrive(DriveLetter); 
      } 
      System.Diagnostics.Process p = new System.Diagnostics.Process(); 
      p.StartInfo.UseShellExecute = false; 
      p.StartInfo.CreateNoWindow = true; 
      p.StartInfo.RedirectStandardError = true; 
      p.StartInfo.RedirectStandardOutput = true; 

      p.StartInfo.FileName = "net.exe"; 
      p.StartInfo.Arguments = " use " + DriveLetter + ": " + '"' + Path + '"' + " " + Password + " /user:" + Username; 
      p.Start(); 
      p.WaitForExit(); 

      string ErrorMessage = p.StandardError.ReadToEnd(); 
      string OuputMessage = p.StandardOutput.ReadToEnd(); 
      if (ErrorMessage.Length > 0) 
      { 
       throw new Exception("Error:" + ErrorMessage); 
      } 
      else 
      { 
       ReturnValue = true; 
      } 
      return ReturnValue; 
     } 
     public static bool DisconnectDrive(string DriveLetter) 
     { 
      bool ReturnValue = false; 
      System.Diagnostics.Process p = new System.Diagnostics.Process(); 
      p.StartInfo.UseShellExecute = false; 
      p.StartInfo.CreateNoWindow = true; 
      p.StartInfo.RedirectStandardError = true; 
      p.StartInfo.RedirectStandardOutput = true; 

      p.StartInfo.FileName = "net.exe"; 
      p.StartInfo.Arguments = " use " + DriveLetter + ": /DELETE"; 
      p.Start(); 
      p.WaitForExit(); 

      string ErrorMessage = p.StandardError.ReadToEnd(); 
      string OuputMessage = p.StandardOutput.ReadToEnd(); 
      if (ErrorMessage.Length > 0) 
      { 
       throw new Exception("Error:" + ErrorMessage); 
      } 
      else 
      { 
       ReturnValue = true; 
      } 
      return ReturnValue; 
     } 

    } 
+0

Я не могу отключить и снова подключиться, потому что он не будет подключаться в первую очередь. – jonathanpeppers

0

Вместо подключенного диска вы могли бы подключиться с использованием общей папки UNC?

Я по-прежнему выдавал себя за пользователя, имеющего доступ к доле.

+0

Наш сторонний процесс, с которым мы взаимодействуем, должен работать с простой буквой диска, такой как f: \ – jonathanpeppers

0

Я действительно делал это раньше, но это было ОЧЕНЬ давным-давно - например, 1997, и Win NT 3.51 с Delphi 2

Я бегу из памяти, но я думаю, что это звучит примерно так: Вы используете Win API:

WNetAddConnection2()

Информация о вызове: http://msdn.microsoft.com/en-us/library/aa385413(VS.85).aspx

вы можете получить с # подписью Pinvoke.net: http://www.pinvoke.net/default.aspx/mpr/WNetAddConnection2.html

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

+0

Я уже реализовал WNetAddConnection2. – jonathanpeppers

+0

@ Джонатан: Вы применили записи о конфигурации в своем посте? Вероятно, он не будет работать с сервисом, который работает как локальная система - вам нужно будет настроить учетную запись домена, имеющую доступ к сети, и соответствующие разрешения для доступа к соединению, которое вы подключаете. Служба должна работать как эта учетная запись, а не как локальная система. – JMarsch

0

Общая концепция, которую следует иметь в виду, состоит в том, что «отображаемые буквы дисков» представляют собой концепцию пользователя, а не концепцию системы. Поэтому, когда Joe входит в компьютер Windows, подключенные диски подключаются к учетной записи пользователя Joe. Когда служба Windows работает, как правило, она работает под учетной записью пользователя LOCAL_SYSTEM, что означает, что LOCAL_SYSTEM не знает о записанных буклетах Джо.

Таким образом, доступ UNC к общим сетевым ресурсам - это путь, который можно использовать при попытке получить доступ к любому удаленному ресурсу из службы Windows. Обратите внимание, что вы можете запустить службу Windows в контексте учетной записи пользователя «Joe», или вы можете создать фиктивную учетную запись AD, названную как «MyServiceAccount», и предоставить права учетной записи для UNC, или вы можете использовать олицетворение и иметь Служба Windows входит на локальную рабочую станцию ​​с использованием функции NetLogon() с дескриптором олицетворения и затем получает доступ к UNC.

Существует множество способов сделать это, но все они относятся к учетным записям пользователей, связанным с подключенными дисками и доступом к UNC.

Удачи, надеюсь, эта информация поможет!

Смежные вопросы