2011-01-03 5 views
1

Я пытаюсь выяснить, существует ли каталог на основе поля ввода от пользователя. Когда пользователь вводит путь, я хочу проверить, существует ли путь на самом деле.проверить, существует ли каталог в сети C#

У меня уже есть код на C#. Он всегда возвращает 0, ЗА ИСКЛЮЧЕНИЕМ для строки «C: \ Program Files» ...

static string checkValidPath(string path) 
{ 
    //Insert your code that runs under the security context of the authenticating user here. 
    using (ImpersonateUser user = new ImpersonateUser("myusername", "", "mypassword")) 
    { 
     //DirectoryInfo d = new DirectoryInfo(quotelessPath); 
     bool doesExist = Directory.Exists(path); 

     //if (d.Exists) 
     if(doesExist) 
     { 
      user.Dispose(); 
      return "1"; 
     } 
     else 
     { 
      user.Dispose(); 
      return "0"; 
     } 
    } 


} 

public class ImpersonateUser : IDisposable 
{ 
    [DllImport("advapi32.dll", SetLastError = true)] 
    private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

    [DllImport("kernel32", SetLastError = true)] 
    private static extern bool CloseHandle(IntPtr hObject); 

    private IntPtr userHandle = IntPtr.Zero; 
    private WindowsImpersonationContext impersonationContext; 

    public ImpersonateUser(string user, string domain, string password) 
    { 
     if (!string.IsNullOrEmpty(user)) 
     { 
      // Call LogonUser to get a token for the user 
      bool loggedOn = LogonUser(user, domain, password, 
        9 /*(int)LogonType.LOGON32_LOGON_NEW_CREDENTIALS*/, 
        3 /*(int)LogonProvider.LOGON32_PROVIDER_WINNT50*/, 
        out userHandle); 
      if (!loggedOn) 
       throw new Win32Exception(Marshal.GetLastWin32Error()); 

      // Begin impersonating the user 
      impersonationContext = WindowsIdentity.Impersonate(userHandle); 
     } 
    } 

    public void Dispose() 
    { 
     if (userHandle != IntPtr.Zero) 
      CloseHandle(userHandle); 
     if (impersonationContext != null) 
      impersonationContext.Undo(); 
    } 
} 

Любая помощь приветствуется. Благодаря!

EDIT 4: Наконец-то найдено решение! См. Ответ ниже. Код BrokenGlass также сработал бы. Мне было проще добавить файл web.config.

EDIT 3: обновленный код для использования функций олицетворения BrokenGlass. Еще не удачи ...

EDIT 2: Я обновил код, чтобы попытаться использовать олицетворение, как предложено ниже. Он все равно терпит неудачу каждый раз. Я предполагаю, что использую олицетворение ненадлежащим образом ...

EDIT: В соответствии с запросом ChrisF, здесь функция, вызывающая функцию checkValidPath.

Frontend ASPX файл ...

$.get('processor.ashx', { a: '7', path: x }, function(o) { 
      alert(o); 
      if (o=="0") { 
       $("#outputPathDivValid").dialog({ 
        title: 'Output Path is not valid! Please enter a path that exists!', 
        width: 500, 
        modal: true, 
        resizable: false, 
        buttons: { 
         'Close': function() { $(this).dialog('close'); } 
        } 
       }); 
      } 
     }); 

Backend ASHX файл ...

public void ProcessRequest (HttpContext context) { 
    context.Response.Cache.SetExpires(DateTime.Now); 
    string sSid = context.Request["sid"]; 
    switch (context.Request["a"]) 
    {//a bunch of case statements here... 
      case "7": 
      context.Response.Write(checkValidPath(context.Request["path"].ToString())); 
      break; 
+0

Все, что есть выглядит правильно, вы подтверждено, что вы получаете в функции? –

+0

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

+0

Является ли параметр Path правильным путем? Это может быть вашей проблемой. – asawyer

ответ

0

Итак, я нашел решение. Я просто добавил олицетворение в файле web.config в папку, в которой существует веб-приложение. Вот код, который я использовал в файле ...

<configuration> 
<appSettings/> 
<connectionStrings/> 
<system.web> 
    <identity impersonate="true" userName="registry:HKLM\Software\medc\sys_content_pub,userName" password="registry:HKLM\Software\medc\sys_content_pub,password"/> 
</system.web> 

я, возможно, пренебрегали, что это веб-приложение. : O Однако, крик идет к BrokenGlass для всех его вкладов. Ваш код работал бы хорошо, если бы я исследовал способ оценки значений реестра.

И вот последняя функция checkValidPath ...

static bool checkValidPath(string path) 
{ 

    string quotelessPath = path.Replace("\"",""); 

    bool doesExist = Directory.Exists(quotelessPath); 

    if(doesExist) 
    { 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 
+0

, это делает то же самое, что и мой ответ только в web.config, по общему признанию, это чище но это не должно иметь значения при работе, если вы правильно использовали олицетворение кода. Вы также должны указать здесь имя пользователя и пароль, нет «суперпользователя» – BrokenGlass

+0

@BrokenGlass. Я это понимаю. Тем не менее, теперь проблема заключалась бы в поиске способа получить userName = "registry: HKLM \ Software \ medc \ sys_content_pub, userName" и password = "registry: HKLM \ Software \ medc \ sys_content_pub, password", чтобы фактически оценить что нибудь. Вместо того, чтобы найти способ сделать это в C#, я просто создал новый файл web.config. –

5

попробуйте

bool doesExist = Directory.Exists(path); 

Ваш код работает для меня, убедитесь, что вы передаёте полный путь, т.е. @"C:\myDir\myDir2" вместо "myDir2"

олицетворять пользователь для сетевого пути попробовать это:

using(ImpersonateUser user = new ImpersonateUser(user, "", password)) 
{ 
    bool doesExist = Directory.Exists(networkPath); 
} 

Это основано на следующем вспомогательном классе:

public class ImpersonateUser : IDisposable 
{ 
    [DllImport("advapi32.dll", SetLastError = true)] 
    private static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken); 

    [DllImport("kernel32", SetLastError = true)] 
    private static extern bool CloseHandle(IntPtr hObject); 

    private IntPtr userHandle = IntPtr.Zero; 
    private WindowsImpersonationContext impersonationContext; 

    public ImpersonateUser(string user, string domain, string password) 
    { 
     if (!string.IsNullOrEmpty(user)) 
     { 
      // Call LogonUser to get a token for the user 
      bool loggedOn = LogonUser(user, domain, password, 
        9 /*(int)LogonType.LOGON32_LOGON_NEW_CREDENTIALS*/, 
        3 /*(int)LogonProvider.LOGON32_PROVIDER_WINNT50*/, 
        out userHandle); 
      if (!loggedOn) 
       throw new Win32Exception(Marshal.GetLastWin32Error()); 

      // Begin impersonating the user 
      impersonationContext = WindowsIdentity.Impersonate(userHandle); 
     } 
    } 

    public void Dispose() 
    { 
     if (userHandle != IntPtr.Zero) 
      CloseHandle(userHandle); 
     if (impersonationContext != null) 
      impersonationContext.Undo(); 
    } 
} 
+0

по какой-то причине, когда я пытаюсь добавить двойные кавычки вокруг ввода пути, он не работает ... –

+0

похоже, что вам не хватает первой строки функции. –

+0

Я обновил код, см. OP, чтобы использовать ваши функции, но теперь я получаю две ошибки. Один говорит, что он не может использовать win32exception, я предполагаю, что мне не хватает класса System.some, и он также жалуется, что пароль не определен. Для чего я инициализирую пароль? –

6

Fro м MSDN page для Exists собственности:

Exists свойства возвращает ложь, если какая-либо ошибка возникает при попытке определить, существует ли указанный файл. Это может происходить в ситуациях, которые вызывают исключения, такие как передача имени файла с недопустимыми символами или слишком много символов, сбой или отсутствующий диск или если у вызывающего устройства нет разрешения на чтение файла.

Итак, выполните одно из следующих действий:

  1. Содержит ли путь любые недопустимые символы?
  2. Это слишком долго?
  3. На самом деле он описывает путь, который существует?
  4. Имеет ли владелец процесса разрешения на чтение файла?

Пункт 4 важен. Хотя «вы» как разработчик может иметь права при тестировании приложения локально, вам нужно убедиться, что учетная запись, на которой запущена программа на сервере, имеет права. Если приложение не будет работать, и это не будет очевидно при попытке повторить проблему.

+0

нет, нет, да, я могу проверить это дважды, но я на 99% положительно могу. –

+0

@Ant - в этом случае я не знаю. Что такое * точная строка, которую вы передаете в качестве пути? – ChrisF

+0

@ChrisF можно настроить с помощью текстового поля ввода html. прямо сейчас его \\ foo.bar.buz \ quk \ ... в место, которое определенно существует. это не правильный формат? –

1

False возвращается, поскольку свойство «существует» означает, что существует каталог, поэтому, если вы передадите путь к файлу в качестве аргумента в конструктор DirectoryInfo, будет возвращено значение false. Вы получите правду, если вы создадите DirectoryInfo с существующим каталогом, переданным в качестве аргумента. Если вы хотите определить, существует ли файл, вы должны его проверить, используя: File.Exists Итак, вы уверены, что path, введенный пользователем, указывает на существующий каталог (а не файл)?

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