ProcessStartInfo.WorkingDirectory and Mapped Network Drives

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Has anyone successfully called the Start() method on a
System.Diagnostics.Process object with the object's
ProcessStartInfo.WorkingDirectory set to a path on a mapped network drive?

For example, if I have "w:" mapped to "\\serverA\share1" and set
ProcessStartInfo.WorkingDirectory = "w:\dir1", my calls to Process.Start()
always fail with the error "The directory name is invalid".

Whereas, if I do the same thing with WorkingDirectory = "c:\dir1", calls to
Process.Start() always succeed.

Before anyone asks, yes the directory "dir1" does exist on w: and is
readable under the user context calling the Process.Start() method.

If no one has successfully executed Process.Start() with WorkingDirectory
pointing to a mapped network drive, does anyone have any (MS) reference
article confirming that this is not possible and perhaps explaining why?

Thanks in advance.
 
Just discovered a critical piece of the puzzle...

The Start() method fails, as described below, only when running as a Windows
Service. When I try the same thing from s straight Console App while logged
in as the service account user, Start() succeed. However, when running as a
Windows Service it doesn't seem I can set WorkingDirectory to any mapped
drives...even though I have confirmed that the mapped drive does exist and is
accessible to the service account.

So, a refinement of my question should read "Has anyone successfully set
ProcessStartInfo.WorkingDirectory to a mapped network drive while running as
a Windows Service?"
 
When a windows service starts, no one is logged into the computer. Until
someone logs in, there are NO mapped drives! So, you will have to use UNC
paths (//server/share1/dir1).
Bob
 
Thanks for the reply Bob. However, I have two comments/questions...

1) While running as a Windows Service, I can map a drive and access it like
a local drive - it's just ProcessStartInfo.WorkingDirectory fails when I set
it to a mapped drive. So, when you say "there are NO mapped drives" I would
argue that there are...once you map them. Did I misunderstand your statement?

2) In my code, ProcessStartInfo.WorkingDirectory doesn't like UNC paths
either. Have you experienced something different?
 
A windows service starts before anyone logs on. At that time, there are
no mapped drives. When you log on, you can see w:, but your service has
failed by then.
Services are designed that way on purpose - all the computer has to do
is start up. SQL Server is a great example - you can set it up, put the
computer in a closet, and leave it alone and still use SQL from a client
machine.
Bob
 
Bob,

With respect, I think you've missed the point of my question and previous
comments - perhaps through a miscommunication of my own.

I'll attempt to clarify one last time...Here's the scenario:

1) I've written a Windows Service (C# and .NET Framework 2.0). This Windows
Service has its properties set such that it runs under the context of a
particular user account. For simplicity's sake, assume this user to be the
Domain Administrator account (DOMAIN\Administrator).

2) In the service's OnStart() event, the first thing I do is map a network
drive by executing the Start() method of a System.Diagnostics.Process object
whose ProcessStartInfo object has been configured such that my service
essentially executes the following command: "net use w: \\serverA\share1".
From this point forward, the mapped network drive "w:" IS available to my
service. Bob, while you are correct that by default no drives are
automatically mapped when a Windows Service starts, you are incorrect in
implying that a service cannot map a network drive or access a mapped drive
once the service is running - it can. I'll be glad to send you example code
if you would like to try it out for yourself.

3) Now that the drive "w:" is mapped and accessible to my service in a
general way (i.e., I can perform a directory listings on "w:", I can write
files to "w:", I can read files from "w:", etc.), I create a new Process
object. With this new Process object, I'd like to explicitly set its
ProcessStartInfo.WorkingDirectory property to a path on "w:" (remember, "w:"
IS available to my service at this point in time).

4) When I set the WorkingDirectory to any path on "w:", the call to Start()
fails. However, when I set the WorkingDirectory to any path on "c:", the
Start() method of the Process object executes just fine. Hence, my problem.

Hopefully, I've made it clear that I'm not having trouble with or confused
about mapping or accessing a mapped network drive from within a service. I
can prove that my service maps the drive and is accessible for things such as
directory listings, file creation, etc.

Rather, what I seek is an understanding why it seems the
ProcessStartInfo.WorkingDirectory doesn't like to be given a path that
incorporates a mapped drive when the Process object's Start() method is
called from within a service. Make more sense?
 
No I understood perfectly. A windows service runs with no users logged
on. Mapped drives are attached to logged on users. Ergo, services NEVER see
mapped drives. That is your problem.
Bob
 
Bob,

I do appreciate your attempts to be helpful, but you are wrong on two points:

1) You do not "understand [what I've written] perfectly."

2) Services CAN, as I described previously, see mapped drives. For proof,
perform the following simplified test (example created using C#, VS2005, and
..NET 2.0 Framework)...

First, create a new Windows Service with the following in its
ServiceBase.OnStart() method:

//=========== Begin Code Snippet ==============
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
proc.StartInfo.FileName = "net";
proc.StartInfo.Arguments = "use w: \\\\serverA\\share1";

proc.Start();
proc.WaitForExit();

System.IO.StreamWriter sw = new
System.IO.StreamWriter("w:\\MappedDriveOutput.txt", false); //note the
reference to mapped drive w:
sw.AutoFlush = true;

System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo("w:"); //again,
note the reference to mapped drive w:
System.IO.FileSystemInfo[] files = dir.GetFileSystemInfos();

foreach (System.IO.FileSystemInfo info in files)
{
sw.WriteLine(info.FullName);
}

sw.Close();
sw.Dispose();
//=========== End Code Snippet ==============

Once you have created your service, install it and run under
DOMAIN\Administrator user account context (making sure DOMAIN\Administrator
has read/write rights to \\serverA\share1).

Make sure there are files in share1 on serverA.

Start the service. The service shall attempt to map drive w: to
\\serverA\share1 as DOMAIN\Administrator, created a file on "w:", and write a
directory listing of "w:" to that file before finishing its OnStart() method.

If you do not get the same results, let me know where it is failing and what
error you are getting and we can try to reconcile. Perhaps there's some
subtle difference in our environments, such as O/S version, etc. (I'm running
on Win2k3, by the way).

Otherwise, if you DO get the appropriate output file, please explain how the
service you created was able to read from and write to "w:" if "w:" was not
mapped and available to the service?

Hopefully, this will move us beyond this sticking point and get back to the
question I'm asking about the ProcessStartInfo.WorkingDirectory property not
accepting a reference to a mapped drive while running as a service.
 
I am afraid your problem is that by the time you map w: with the net use
command, the start process code already tried to access it. You might
overcome the problem and achieve what you want by specifying your command as
in:

@"cmd /c net use w: \\serverA\Share1 && cd /d w:\"

and let the default directory where it was for the start process that works.


/LM

mhetherington said:
Bob,

I do appreciate your attempts to be helpful, but you are wrong on two
points:

1) You do not "understand [what I've written] perfectly."

2) Services CAN, as I described previously, see mapped drives. For proof,
perform the following simplified test (example created using C#, VS2005,
and
.NET 2.0 Framework)...

First, create a new Windows Service with the following in its
ServiceBase.OnStart() method:

//=========== Begin Code Snippet ==============
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
proc.StartInfo.FileName = "net";
proc.StartInfo.Arguments = "use w: \\\\serverA\\share1";

proc.Start();
proc.WaitForExit();

System.IO.StreamWriter sw = new
System.IO.StreamWriter("w:\\MappedDriveOutput.txt", false); //note the
reference to mapped drive w:
sw.AutoFlush = true;

System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo("w:");
//again,
note the reference to mapped drive w:
System.IO.FileSystemInfo[] files = dir.GetFileSystemInfos();

foreach (System.IO.FileSystemInfo info in files)
{
sw.WriteLine(info.FullName);
}

sw.Close();
sw.Dispose();
//=========== End Code Snippet ==============

Once you have created your service, install it and run under
DOMAIN\Administrator user account context (making sure
DOMAIN\Administrator
has read/write rights to \\serverA\share1).

Make sure there are files in share1 on serverA.

Start the service. The service shall attempt to map drive w: to
\\serverA\share1 as DOMAIN\Administrator, created a file on "w:", and
write a
directory listing of "w:" to that file before finishing its OnStart()
method.

If you do not get the same results, let me know where it is failing and
what
error you are getting and we can try to reconcile. Perhaps there's some
subtle difference in our environments, such as O/S version, etc. (I'm
running
on Win2k3, by the way).

Otherwise, if you DO get the appropriate output file, please explain how
the
service you created was able to read from and write to "w:" if "w:" was
not
mapped and available to the service?

Hopefully, this will move us beyond this sticking point and get back to
the
question I'm asking about the ProcessStartInfo.WorkingDirectory property
not
accepting a reference to a mapped drive while running as a service.


Bob Milton said:
No I understood perfectly. A windows service runs with no users
logged
on. Mapped drives are attached to logged on users. Ergo, services NEVER
see
mapped drives. That is your problem.
Bob

message
 
Luc,

Thanks for the reply. I'm not having problems with the code example I gave
- it works as described.

Frustratingly, this thread has strayed far from my original question due to
the confusion over whether or not you can map and access network drives from
within a service. To get the thread back on track, please consider the
following:

a) A service starts and maps "w:" (please don't anyone tell me this cannot
be done, because it can...see my code example below and everything I've
written previously in this thread).

b) Assume the service goes to sleep for some period of time (seconds,
minutes...it doesn't matter). This will eliminate Luc's suspicion that the
drive has not successfully mapped by the time Start() is called on the
Process object.

c) Upon waking up, assume the service creates two System.Diagnostics.Process
objects, the only difference between the two being that the first has it's
ProcessStartInfo.WorkingDirectory set to a path on the (local) "c:" drive and
the second has its ProcessStartInfo.WorkingDirectory set to a path on the
(mapped) "w:" drive.

In this case, the process with its WorkingDirectory set to the "c:" drive
succeeds in having its Working Directory set, but the process with its
WorkingDirectory set to a path on "w:" IGNORES the WorkingDirectory setting
and defaults to "C:\Windows".

If the same "test" is performed outside of a service, the WorkingDirectory
is properly set in both cases. Therefore, I know the WorkingDirectory
property itself is not limited to local drives only. It's something specific
to when the code runs as a service.

(Note: If you're tempted to tell me that it's because you cannot map a
drive as a service, save your typing...Re-read all that's been previously
written in this thread, run the sample code, and you'll see that you CAN map
a drive as a service AND access it.)

So, why doesn't ProcessStartInfo.WorkingDirectory seem to like being pointed
to a network drive when running as a service? This is the question I'm
trying to find an answer/workaround for. Can anyone shed some light
(specifically on setting ProcessStartInfo.WorkingDirectory to a mapped drive
while running as a service)?

Luc E. Mistiaen said:
I am afraid your problem is that by the time you map w: with the net use
command, the start process code already tried to access it. You might
overcome the problem and achieve what you want by specifying your command as
in:

@"cmd /c net use w: \\serverA\Share1 && cd /d w:\"

and let the default directory where it was for the start process that works.


/LM

mhetherington said:
Bob,

I do appreciate your attempts to be helpful, but you are wrong on two
points:

1) You do not "understand [what I've written] perfectly."

2) Services CAN, as I described previously, see mapped drives. For proof,
perform the following simplified test (example created using C#, VS2005,
and
.NET 2.0 Framework)...

First, create a new Windows Service with the following in its
ServiceBase.OnStart() method:

//=========== Begin Code Snippet ==============
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
proc.StartInfo.FileName = "net";
proc.StartInfo.Arguments = "use w: \\\\serverA\\share1";

proc.Start();
proc.WaitForExit();

System.IO.StreamWriter sw = new
System.IO.StreamWriter("w:\\MappedDriveOutput.txt", false); //note the
reference to mapped drive w:
sw.AutoFlush = true;

System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo("w:");
//again,
note the reference to mapped drive w:
System.IO.FileSystemInfo[] files = dir.GetFileSystemInfos();

foreach (System.IO.FileSystemInfo info in files)
{
sw.WriteLine(info.FullName);
}

sw.Close();
sw.Dispose();
//=========== End Code Snippet ==============

Once you have created your service, install it and run under
DOMAIN\Administrator user account context (making sure
DOMAIN\Administrator
has read/write rights to \\serverA\share1).

Make sure there are files in share1 on serverA.

Start the service. The service shall attempt to map drive w: to
\\serverA\share1 as DOMAIN\Administrator, created a file on "w:", and
write a
directory listing of "w:" to that file before finishing its OnStart()
method.

If you do not get the same results, let me know where it is failing and
what
error you are getting and we can try to reconcile. Perhaps there's some
subtle difference in our environments, such as O/S version, etc. (I'm
running
on Win2k3, by the way).

Otherwise, if you DO get the appropriate output file, please explain how
the
service you created was able to read from and write to "w:" if "w:" was
not
mapped and available to the service?

Hopefully, this will move us beyond this sticking point and get back to
the
question I'm asking about the ProcessStartInfo.WorkingDirectory property
not
accepting a reference to a mapped drive while running as a service.


Bob Milton said:
No I understood perfectly. A windows service runs with no users
logged
on. Mapped drives are attached to logged on users. Ergo, services NEVER
see
mapped drives. That is your problem.
Bob

message
Bob,

With respect, I think you've missed the point of my question and
previous
comments - perhaps through a miscommunication of my own.

I'll attempt to clarify one last time...Here's the scenario:

1) I've written a Windows Service (C# and .NET Framework 2.0). This
Windows
Service has its properties set such that it runs under the context of a
particular user account. For simplicity's sake, assume this user to be
the
Domain Administrator account (DOMAIN\Administrator).

2) In the service's OnStart() event, the first thing I do is map a
network
drive by executing the Start() method of a System.Diagnostics.Process
object
whose ProcessStartInfo object has been configured such that my service
essentially executes the following command: "net use w:
\\serverA\share1".
From this point forward, the mapped network drive "w:" IS available to
my
service. Bob, while you are correct that by default no drives are
automatically mapped when a Windows Service starts, you are incorrect
in
implying that a service cannot map a network drive or access a mapped
drive
once the service is running - it can. I'll be glad to send you example
code
if you would like to try it out for yourself.

3) Now that the drive "w:" is mapped and accessible to my service in a
general way (i.e., I can perform a directory listings on "w:", I can
write
files to "w:", I can read files from "w:", etc.), I create a new
Process
object. With this new Process object, I'd like to explicitly set its
ProcessStartInfo.WorkingDirectory property to a path on "w:" (remember,
"w:"
IS available to my service at this point in time).

4) When I set the WorkingDirectory to any path on "w:", the call to
Start()
fails. However, when I set the WorkingDirectory to any path on "c:",
the
Start() method of the Process object executes just fine. Hence, my
problem.

Hopefully, I've made it clear that I'm not having trouble with or
confused
about mapping or accessing a mapped network drive from within a
service.
I
can prove that my service maps the drive and is accessible for things
such
as
directory listings, file creation, etc.

Rather, what I seek is an understanding why it seems the
ProcessStartInfo.WorkingDirectory doesn't like to be given a path that
incorporates a mapped drive when the Process object's Start() method is
called from within a service. Make more sense?

:

A windows service starts before anyone logs on. At that time,
there
are
no mapped drives. When you log on, you can see w:, but your service
has
failed by then.
Services are designed that way on purpose - all the computer has
to
do
is start up. SQL Server is a great example - you can set it up, put
the
computer in a closet, and leave it alone and still use SQL from a
client
machine.
Bob
message
Thanks for the reply Bob. However, I have two comments/questions...

1) While running as a Windows Service, I can map a drive and access
it
like
a local drive - it's just ProcessStartInfo.WorkingDirectory fails
when
I
set
it to a mapped drive. So, when you say "there are NO mapped drives"
I
would
argue that there are...once you map them. Did I misunderstand your
statement?

2) In my code, ProcessStartInfo.WorkingDirectory doesn't like UNC
paths
either. Have you experienced something different?

:

When a windows service starts, no one is logged into the
computer.
Until
someone logs in, there are NO mapped drives! So, you will have to
use
UNC
paths (//server/share1/dir1).
Bob

message
Just discovered a critical piece of the puzzle...

The Start() method fails, as described below, only when running
as a
Windows
Service. When I try the same thing from s straight Console App
while
logged
in as the service account user, Start() succeed. However, when
running
as
a
Windows Service it doesn't seem I can set WorkingDirectory to any
mapped
drives...even though I have confirmed that the mapped drive does
exist
and
is
accessible to the service account.

So, a refinement of my question should read "Has anyone
successfully
set
ProcessStartInfo.WorkingDirectory to a mapped network drive while
running
as
a Windows Service?"

:

Has anyone successfully called the Start() method on a
System.Diagnostics.Process object with the object's
ProcessStartInfo.WorkingDirectory set to a path on a mapped
network
drive?

For example, if I have "w:" mapped to "\\serverA\share1" and set
ProcessStartInfo.WorkingDirectory = "w:\dir1", my calls to
Process.Start()
always fail with the error "The directory name is invalid".

Whereas, if I do the same thing with WorkingDirectory =
"c:\dir1",
calls
to
Process.Start() always succeed.

Before anyone asks, yes the directory "dir1" does exist on w:
and
is
readable under the user context calling the Process.Start()
method.

If no one has successfully executed Process.Start() with
WorkingDirectory
pointing to a mapped network drive, does anyone have any (MS)
reference
article confirming that this is not possible and perhaps
explaining
why?

Thanks in advance.
 
b) Assume the service goes to sleep for some period of time (seconds,
minutes...it doesn't matter). This will eliminate Luc's suspicion that
the
drive has not successfully mapped by the time Start() is called on the
Process object.

That is not what I said. I just said that if your start a process with a
command 'net use w:..." you cannot set its default directory (before the
create) to w:
I know you can map drives in services as I do that too :-)

For your last post, I am not sure your drive mappings are automatically
inherited to processes you create with a bare CreateProcess from your
service. What does a process created like you do (as a sub-process of your
service) shows when you pass a simple 'net use' command to show what it
knows about mapped drives...

/LM
 
Hi Luc,

Thanks for the reply (and the confirmation that I'm not the only person in
the world mapping drives from within services with success ;-).

Regarding Processes created by a service and their ability to inherit the
service process's mapped drives...I have confirmed they do.

I haven't tested specifically with "net use" as you suggested, but along the
same lines, I have tested spawning a Process that launches a custom EXE, who
operates on "w:" with success (writing files to "w:", doing a directory on
"w:", etc.). So, yes, I have confirmed that the spawned process does inherit
the mapped drives of the launching service process.

So, back to the question of why can't I set
ProcessStartInfo.WorkingDirectory to a path on a mapped drive when spawning
processes from a service process? Why does it ignore my setting and default
to "c:\windows"? Any other thoughts?
 
So, back to the question of why can't I set
ProcessStartInfo.WorkingDirectory to a path on a mapped drive when
spawning
processes from a service process? Why does it ignore my setting and
default
to "c:\windows"? Any other thoughts?

I can only guess here, that during the process creation, there are various
phases and that the settings of the default directory occurs before the rest
of the process context (as inherited environment and mapped drives) .

If the drive is well mapped in the end, you could try to use
'Directory.SetCurrentDirectory(...)' in your OnStart, to set the default
directory at a later stage, once the process is fully operational. Or if it
is an external program you don't have access to, use the 'cmd /c cd /d MyDir
&& YourProgram' trick as I suggested in my first post (I responded with that
because I saw in my older projects that was what I did).

/LM
 
Back
Top