简体   繁体   中英

Accessing mapped folder from a Windows Service written in C#

I have a windows service which polls for a specific folder for creation of new files. This works fine when the folder is in one of the local drives such as C: or D: The service fails to find a folder on a mapped drive.

Here is the code which does the checking for folder exist before polling:

System.Security.Principal.WindowsIdentity userIdentity =
            System.Security.Principal.WindowsIdentity.GetCurrent();
            System.Security.Principal.WindowsPrincipal principal =
                new System.Security.Principal.WindowsPrincipal(userIdentity);

            MappedDriveResolver mdr = new MappedDriveResolver();
            if (mdr.isNetworkDrive(folderPath))
            {
                LoggingAppWrapper.LogDeveloperMessage(folderPath + " is on a Mapped    drive", 1, TraceEventType.Information, string.Empty);

            }

MappedDriveResolver is a class that I found here How do I determine a mapped drive's actual path?

The code in that link works fine from a simple console application, but fails when it is part of windows service. Any suggestions as to what has to be done for the code to work for a windows service?

Regards.

I would recommend you configure your service to use UNC paths for folders not on the server running the service.

Mapped drives are a usability feature for users and as such they are specific to that users profile/environment. Meaning, when you login you may have a drive X: that is mapped to \\\\server1\\share1 but when I login my drive X: could be mapped to \\\\server2\\share2 instead. The actual mapping process is either saved as part of your profile with the "Reconnect at logon" or is handled by a logon script.

You need to check what account the service is running under and make sure that mapped drive exists for that user environment (This might help How to map a network drive to be used by a service ).

Edit:

The reason your console application works and the service doesn't is because of the differences between the environment they are running in.

To illustrate this, take this console application, compile it and then run it as a Schedule Task. Set the "path" variable to be a mapped drive that your user can access.

    static void Main(string[] args) {
        MappedDriveResolver mdr = new MappedDriveResolver();
        string logfile;
        string path = @"I:\";
        string[] files;

        // Write out "log" file to where this is running from
        logfile = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
        logfile = Path.Combine(logfile, "log.txt");

        using (StreamWriter sw = new StreamWriter(logfile, true)) {

            try {
                sw.WriteLine("Checking path " + path);
                if (mdr.isNetworkDrive(path)) {
                    sw.WriteLine("Network Drive: Yes");
                } else {
                    sw.WriteLine("Network Drive: No");
                }
            } catch (Exception ex) {
                sw.WriteLine("Exception: " + ex.Message);
            }

            try {
                sw.WriteLine("Resolve path " + path);
                string newpath = mdr.ResolveToUNC(path);
                sw.WriteLine("Resolved path " + newpath);
            } catch (Exception ex) {
                sw.WriteLine("Exception: " + ex.Message);
            }

            try {
                sw.WriteLine("Get file list from " + path);
                files = Directory.GetFiles(path);
                if (files == null || files.Length == 0) {
                    sw.WriteLine("No files found");
                } else {
                    sw.WriteLine(string.Format("Found {0} files.", files.Length));
                }
            } catch (Exception ex) {
                sw.WriteLine("Exception: " + ex.Message);
            }

            sw.Flush();
            sw.Close();
        }
    }

Note: This is with the Windows 7 Task Scheduler

Test 1: Just run the app by double-clicking on it.
Result: Success

Test 2: Configure scheduled task to run as your user account with "Run only when user is logged on"
Result: Success

Test 3: Configure scheduled task to run as your user account with "Run whether user is logged on or not"
Result: Exceptions

Test 4: Configure schedule task to run as "Local Service" account.
Result: Exceptions

Test 1 & 2 work because they are using the currently logged in user environment including the mapped drives that are part of it.

Test 3 & 4 fail because they have their own user environment created for them, which does not have any mapped drives configured. It escapes me at the moment what the differences there are, but an "interactive" and "non-interactive" environment are different in some significant ways.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM