开发者

check if directory exists on the network c#

开发者 https://www.devze.com 2023-02-02 12:18 出处:网络
I am trying to see if a directory exists based on an input field from the user. When the user types in the path, I want to check if the path actually exists.

I am trying to see if a directory exists based on an input field from the user. When the user types in the path, I want to check if the path actually exists.

I have some C# code already. It always returns 0, EXCEPT for the string "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 use开发者_StackOverflowr
            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();
    }
}

Any help is appreciated. Thanks!

EDIT 4: Finally found a solution! See answer below. BrokenGlass's code would've worked as well. I found it quicker to just add a web.config file.

EDIT 3: updated code to use BrokenGlass's impersonation functions. Still no luck...

EDIT 2: I updated the code to try and use impersonation as suggested below. It still fails everytime. I assume I am using impersonation improperly...

EDIT: As requested by ChrisF, here is the function that calls the checkValidPath function.

Frontend aspx file...

$.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 file...

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;


From the MSDN page for the Exists property:

The Exists property returns false if any error occurs while trying to determine if the specified file exists. This can occur in situations that raise exceptions such as passing a file name with invalid characters or too many characters, a failing or missing disk, or if the caller does not have permission to read the file.

So, do any of the following apply:

  1. Does the path contain any invalid characters?
  2. Is it too long?
  3. Does it actually describe a path that exists?
  4. Does the owner of the process have permissions to read the file?

Point 4 is important. While "you" as developer may have rights while testing the application locally, you need to make sure that the account running the program on the server has rights. If it doesn't the application will fail and it won't be obvious when you try to repeat the problem.


try

 bool doesExist = Directory.Exists(path);

Your code also works for me, make sure you pass it a full path, i.e. @"C:\myDir\myDir2" instead of "myDir2"

To impersonate a user for a network path try this:

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

This is based on the following helper class:

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


False is returned since property 'Exists' means if directory exists - so, if you pass a file path as an argument to DirectoryInfo constructor, a false will be returned. You'll got a true if you create a DirectoryInfo with an existing directory passed as an argument. If you want to determine if file exists, you should check it using: File.Exists So, are you sure that the path entered by user points to existing directory (not a file)?


All the info is here : http://msdn.microsoft.com/en-us/library/system.io.directory.exists.aspx

Example:

Directory.Exists(myPath);


So I found the solution. I simply added the impersonation in a web.config file to the folder where the web app exists. Here is the code I used in the file...

<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>

I may have neglected that this is a web app. :O However, shout out goes to BrokenGlass for all his contributions. Your code would've worked fine if I researched a way to evaluate the registry values.

And here is the final checkValidPath function...

static bool checkValidPath(string path)
{

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

    bool doesExist = Directory.Exists(quotelessPath);

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

精彩评论

暂无评论...
验证码 换一张
取 消