| | |
Console App, Spawned From Service, File IO
Please support our C# advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
Brief Summary
I've written a Windows Service. It uses Process.Start() to launch a Console Application. The console application performs a File.Copy(), to copy a file from the local file system to a network share.
Problem: The file copy fails. I get an exception that tells me "part of the path could not be found".
When I run the Console Application directly, I don't get the error.
My Guess: I'm guessing that services, and processes spawned by services, do not have permissions to access non-local resources, including network shares.
My Attempted Fix: Run the service under a different user account. It didn't work.
Details
This is for a large transactional processing job. There is a dedicated server that periodically receives (through web services) thousands upon thousands of "transactions". These take the form of individual files, organized into a 5-level hierarchy. Each level has a folder, so the folder structure might be:
C:\OUTPUT\LEVEL_A\LEVEL_B\LEVEL_C\LEVEL_D\files
The "files" represent the individual transations. When a particular "LEVEL_D" is complete, a log file is created.
It can take DAYS to generate all the files. Currently, when the process is complete, someone manually organizes and processes the transations. Yuck.
My Windows Service implements a FileWatcher to look for the creation of the "log" files. When a log file is created, that means there is a "batch" of transactions that can be processed. When a log file is completed, I use System.Diagnostics.Process.Start() to launch a Console Application.
The Console Application contains no User Interface. All it does, really, is file i/o. One of the final steps is to take a newly created file (a pre-processed, concatenation of a transaction "batch") and copy it to another server for final production. It's this step that fails.
I've written a Windows Service. It uses Process.Start() to launch a Console Application. The console application performs a File.Copy(), to copy a file from the local file system to a network share.
Problem: The file copy fails. I get an exception that tells me "part of the path could not be found".
When I run the Console Application directly, I don't get the error.
My Guess: I'm guessing that services, and processes spawned by services, do not have permissions to access non-local resources, including network shares.
My Attempted Fix: Run the service under a different user account. It didn't work.
Details
This is for a large transactional processing job. There is a dedicated server that periodically receives (through web services) thousands upon thousands of "transactions". These take the form of individual files, organized into a 5-level hierarchy. Each level has a folder, so the folder structure might be:
C:\OUTPUT\LEVEL_A\LEVEL_B\LEVEL_C\LEVEL_D\files
The "files" represent the individual transations. When a particular "LEVEL_D" is complete, a log file is created.
It can take DAYS to generate all the files. Currently, when the process is complete, someone manually organizes and processes the transations. Yuck.
My Windows Service implements a FileWatcher to look for the creation of the "log" files. When a log file is created, that means there is a "batch" of transactions that can be processed. When a log file is completed, I use System.Diagnostics.Process.Start() to launch a Console Application.
The Console Application contains no User Interface. All it does, really, is file i/o. One of the final steps is to take a newly created file (a pre-processed, concatenation of a transaction "batch") and copy it to another server for final production. It's this step that fails.
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
Is there no brave soul willing to take a stab at this? Let me re-hash it in case the above isn't clear.
I get the following error:
The code that causes the error (I'm using the "PHP" tags, but this is C# code, of course):
[PHP]if (!Directory.Exists(sack_destination + tape_name))
{
Directory.CreateDirectory(sack_destination + tape_name);
}[/PHP]
"sack_destination" is a string that equates to "z:\mer". This is a mapped drive, a network share.
The code is contained in a Console Application, which is launched from a Windows Service application using System.Diagnostics.Process.Start.
I have tried running the service under the LocalSystem account, and as a local user account with Administrative + "run as service" privileges. The same error in each case.
I also tried running the service under NetworkResource account, but the service failed to start, with no specific error message, so I'm not sure what the problem is there.
The error does NOT occur when I manually run or debug the Console application.
What privileges are needed in order for an application spawned by a service to access network resources? Can those privileges be granted programmatically? In other words, can the service launch the process with specific credentials? If so, how (code snippet)?
I get the following error:
•
•
•
•
An unhandled exception of type 'System.IO.DirectoryNotFoundException' occurred in mscorlib.dll
Additional information: Could not find a part of the path "z:\".
[PHP]if (!Directory.Exists(sack_destination + tape_name))
{
Directory.CreateDirectory(sack_destination + tape_name);
}[/PHP]
"sack_destination" is a string that equates to "z:\mer". This is a mapped drive, a network share.
The code is contained in a Console Application, which is launched from a Windows Service application using System.Diagnostics.Process.Start.
I have tried running the service under the LocalSystem account, and as a local user account with Administrative + "run as service" privileges. The same error in each case.
I also tried running the service under NetworkResource account, but the service failed to start, with no specific error message, so I'm not sure what the problem is there.
The error does NOT occur when I manually run or debug the Console application.
What privileges are needed in order for an application spawned by a service to access network resources? Can those privileges be granted programmatically? In other words, can the service launch the process with specific credentials? If so, how (code snippet)?
•
•
Join Date: Dec 2004
Posts: 1,655
Reputation:
Solved Threads: 35
Following my pattern in the C# forum, I'll answer my own question.
The issue is that the LocalSystem account, which most services run under by default, runs in it's own context. Thus, it doesn't have access to USER drive mappings.
Or, as a very obscure and unenlightening MSDN Article puts it:
The article then goes on to display massive code listings as a "work-around". Ignore all of that. The two relevant pieces of information are that you cannot use DRIVE MAPPINGS.
You can, however, use UNC Paths:
\\COMPUTER_NAME\SharedFolder\
The second clue is that the account used by the service, and thus by extension all processes it spawns, must have rights to the share. A "LocalSystem" account on a specific machine has no such rights. So, the service must run under a "User Account".
That's an inconvenience, to be sure, but can be handled by good installation documentation. In my case, my service application will be installed on the production machine by yours truly, so I can manually change the service Log On to a local user account.
When you use the Services applet in the Control Panel to do this, it will automatically add the requisite "Run as a service" privilege to that account.
Problem solved!
The issue is that the LocalSystem account, which most services run under by default, runs in it's own context. Thus, it doesn't have access to USER drive mappings.
Or, as a very obscure and unenlightening MSDN Article puts it:
•
•
•
•
A service that runs under a LocalSystem account or under a local user account can only access mapped drives that the service creates. Mapped drives are stored for each logon session. If a service runs under a LocalSystem account or under a local user account that does not create certain mapped drives, the service cannot access these mapped drives. Additionally, a service that runs under a local user account that creates certain mapped drives also receives a new set of mapped drives if you log off and then you log on again as the same local user.
You can, however, use UNC Paths:
\\COMPUTER_NAME\SharedFolder\
The second clue is that the account used by the service, and thus by extension all processes it spawns, must have rights to the share. A "LocalSystem" account on a specific machine has no such rights. So, the service must run under a "User Account".
That's an inconvenience, to be sure, but can be handled by good installation documentation. In my case, my service application will be installed on the production machine by yours truly, so I can manually change the service Log On to a local user account.
When you use the Services applet in the Control Panel to do this, it will automatically add the requisite "Run as a service" privilege to that account.
Problem solved!
•
•
Join Date: Apr 2006
Posts: 1
Reputation:
Solved Threads: 0
•
•
•
•
Originally Posted by tgreer
No, not a mapped drive by drive letter, only by UNC path. And the drive permissions will have to be assigned to the Administrator, rather than to "some user of the domain". At least, that was my experience.
![]() |
Similar Threads
- Help make Console App Open in fullscreen. (C++)
- MFC File I/O Philosophy questions/clarifications (C++)
- Can you add pictures/sounds in a win32 console app? (C)
Other Threads in the C# Forum
- Previous Thread: problem with login page
- Next Thread: XmlTextReader.ReadBase64
| Thread Tools | Search this Thread |
.net access activedirectory ado.net algorithm array barchart bitmap box broadcast buttons c# check checkbox client color combobox control conversion csharp custom database datagrid datagridview dataset datetime degrees development disabled displayingopenforms draganddrop drawing encryption enum event excel exectuable file files form format forms ftp function gdi+ httpwebrequest image index index-error input install java label list listbox listener mandelbrot math mathematics mouseclick mysql operator path photoshop picturebox pixelinversion post prime programming radians regex remote remoting richtextbox serialization server setup sleep socket sql statistics stream string table tcp text textbox thread time timer update user usercontrol validation visualstudio webbrowser windows winforms wpf xml






