Starting a process from within a web service

D

dushkin

Hi all.

I have the following code in my Web Service implementation:

Process p = null;
try
{
string targetDir;
p = new Process();
p.StartInfo.FileName = @"c:\copystam.bat";
p.StartInfo.CreateNoWindow = false;

p.Start();

return true;
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace.ToString());

return false;
}

The batch file does not execute. No exception is catched.

I am running on Win7, IIS 7.5.
.Net 4

Thanks!
 
B

bradbury9

Hi all.

 I have the following code in my Web Service implementation:

            Process p = null;
            try
            {
                string targetDir;
                p = new Process();
                p.StartInfo.FileName = @"c:\copystam.bat";
                p.StartInfo.CreateNoWindow = false;

                p.Start();

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception Occurred :{0},{1}",
                            ex.Message, ex.StackTrace.ToString());

                return false;
            }

 The batch file does not execute. No exception is catched.

 I am running on Win7, IIS 7.5.
 .Net 4

Thanks!

Check permissions on file c:\copystam.bat and the user the webservice
(the application pool) is running into.
Also the Console.WriteLine sounds strange to me, a web service is not
a console application. Try Debug.WriteLine instead.
 
D

dushkin

Check permissions on file c:\copystam.bat and the user the webservice
(the application pool) is running into.
Also the Console.WriteLine sounds strange to me, a web service is not
a console application. Try Debug.WriteLine instead.

Thank you.

Regarding the writeline - this is a minor issue, but thanks.
Regarding the bat file permissions - I gave it an everyone use with
all the permissions. Also, all the other users are with all
permisions.
Regarding the application pool - it is ASP.NET v4.0. How do I control
it's permissions??
 
M

Marcel Müller

Hi all.

I have the following code in my Web Service implementation:

Process p = null;
try
{
string targetDir;
p = new Process();
p.StartInfo.FileName = @"c:\copystam.bat";
p.StartInfo.CreateNoWindow = false;

You can't start batch files. They are simply text files.
Only a command interpreter can execute them. The command interpreter in
Windows is usually CMD.EXE. So you need to start CMD.EXE an pass the
batch file as an argument. Most likely you want to use the /C option.

This raises the new point how to catch errors from the batch file. You
might want to check the StandardError handle from the command
interpreter. And, of course, the batch file should reasonable deal with
the %ERRORLEVEL% pseudo variable after taking further actions.
p.Start();

return true;
}
catch (Exception ex)
{
Console.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace.ToString());

return false;
}

The batch file does not execute. No exception is catched.

You did not check the return code from the process. Process.ExitCode is
your friend.

I am running on Win7, IIS 7.5.
.Net 4

By the way you will have to check for security issues. Running in an web
service environment your process will be started either as the currently
authenticated web service user or as anonymous IIS user, depending on
the impersonation setting. So your user needs to have the appropriate
permissions on your web server to start the task. Note that this
permissions are a potential vulnerability.


Marcel
 
D

dushkin

You can't start batch files. They are simply text files.
Only a command interpreter can execute them. The command interpreter in
Windows is usually CMD.EXE. So you need to start CMD.EXE an pass the
batch file as an argument. Most likely you want to use the /C option.

This raises the new point how to catch errors from the batch file. You
might want to check the StandardError handle from the command
interpreter. And, of course, the batch file should reasonable deal with
the %ERRORLEVEL% pseudo variable after taking further actions.





You did not check the return code from the process. Process.ExitCode is
your friend.


By the way you will have to check for security issues. Running in an web
service environment your process will be started either as the currently
authenticated web service user or as anonymous IIS user, depending on
the impersonation setting. So your user needs to have the appropriate
permissions on your web server to start the task. Note that this
permissions are a potential vulnerability.

Marcel

Thank you Marcel.

So I modified the code to:

Process p = null;
try
{
string targetDir;
p = new Process();
p.StartInfo.FileName = @"c:\cmd.exe/C";
p.StartInfo.Arguments = @"c:\stm\copystam.bat";
p.StartInfo.CreateNoWindow = false;

p.Start();

return true;
}
catch (Exception ex)
{
Debug.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace.ToString());

return false;
}

Did I performed the changes as you meant?

No change in product, though... :-(

If relevant, this is the command in the batch file: copy app.config
app1.config
And the app.config is in c:\stm

Thanks!!!
 
P

Phil Hunt

Can I ask you if the process run on the server or the client ? I am think
about doing something similar.

Thanks
 
M

Marcel Müller

Thank you Marcel.

So I modified the code to:

Process p = null;
try
{
string targetDir;
p = new Process();
p.StartInfo.FileName = @"c:\cmd.exe/C";
p.StartInfo.Arguments = @"c:\stm\copystam.bat";

There is nothing like C:\cmd.exe. Usually it is located at
c:\windows\system32\cmd.exe, but it depends on your Windows installation.
Furthermore /C is part of the command line arguments rather than the
executable file.
p.StartInfo.CreateNoWindow = false;

p.Start();

return true;
}
catch (Exception ex)
{
Debug.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace.ToString());

return false;
}

Did I performed the changes as you meant?

No change in product, though... :-(

You still do not check for the exit code. You need to join the spawned
process, before you read the ExitCode.


Marcel
 
M

MiB

Can I ask you if the process run on the server or the client ? I am think
about doing something similar.

A web service cannot start anything on a client. Praise the Lord.

Just my €.02

MiB.
 
A

Arne Vajhøj

Can I ask you if the process run on the server or the client ? I am think
about doing something similar.

"within a web service", "Web Service implementation" and "IIS 7.5"
somewhat indicates that the code is executed server side.

Do you want to run something client side or server side?

Arne
 
A

Arne Vajhøj

So I modified the code to:

Process p = null;
try
{
string targetDir;
p = new Process();
p.StartInfo.FileName = @"c:\cmd.exe/C";
p.StartInfo.Arguments = @"c:\stm\copystam.bat";
p.StartInfo.CreateNoWindow = false;

p.Start();

return true;
}
catch (Exception ex)
{
Debug.WriteLine("Exception Occurred :{0},{1}",
ex.Message, ex.StackTrace.ToString());

return false;
}

Did I performed the changes as you meant?

No. But Marcel already explained that.
If relevant, this is the command in the batch file: copy app.config
app1.config
And the app.config is in c:\stm

Why not just use File.Copy in the .NET framework to copy the file
and avoid all the hassle of Process.Start ?

Arne
 
D

dushkin

There is nothing like C:\cmd.exe. Usually it is located at
c:\windows\system32\cmd.exe, but it depends on your Windows installation.
Furthermore /C is part of the command line arguments rather than the
executable file.















You still do not check for the exit code. You need to join the spawned
process, before you read the ExitCode.

Marcel

Thnaks for the remark. You are right of course.
So I changed it like this:


int ExitCode;
ProcessStartInfo ProcessInfo;
Process process;

ProcessInfo = new ProcessStartInfo("cmd.exe", @"/c c:
\stm\copystam.bat");
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
// *** Redirect the output ***
ProcessInfo.RedirectStandardError = true;
ProcessInfo.RedirectStandardOutput = true;

process = Process.Start(ProcessInfo);
//process.WaitForExit();

// *** Read the streams ***
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();

ExitCode = process.ExitCode;

Debug.WriteLine("output>>" +
(String.IsNullOrEmpty(output) ? "(none)" : output));
Debug.WriteLine("error>>" +
(String.IsNullOrEmpty(error) ? "(none)" : error));
Debug.WriteLine("ExitCode: " + ExitCode.ToString(),
"ExecuteCommand");
process.Close();

The code processing halts on Process.Start until it timesout after a
minute.

NOTE!!!! I do have cmd.exe in the task manager!!!

Also, I tried also to load notepad.exe in the same way like here and
like in the former posts. I do see the notepad.exe process listed in
the task manager. But I don't see the notepad itself...

Thanks.
 
D

dushkin

 > Can I ask you if the process run on the server or the client ? I am think
 > about doing something similar.

"within a web service", "Web Service implementation" and "IIS 7.5"
somewhat indicates that the code is executed server side.

Do you want to run something client side or server side?

Arne

The final intention is of course to put it on a server machine , as it
is a web service.
But in the meantime I am tring to dubug it from my Visual studio,
which is on my PC, by attaching the procees to the w3wp.exe process.
 
D

dushkin

No. But Marcel already explained that.


Why not just use File.Copy in the .NET framework to copy the file
and avoid all the hassle of Process.Start ?

Arne

Running the batch file is just a simple example to test the code. I
also tried to run notepad.exe.

I did see both cmd.exe and notepad.exe in the task managaer!!!!

But I didn't see a copied file nor the UI of the notepad...

BTW, My final aim is to be able to run autoit scripts on remote
computers.
 
D

dushkin

This is for all the kind fellas that try to help me:

I found some advice to use ASP.NET Impersonation Authentication.
I started to do it (changed this property in the Web Service
Authentication configuration part in IIS7.5 to true) and changing the
Application pool to classic, but the web service did not load and gave
me an error.
I was affraid to continue and dive into this change, but is it the
correct direction?...

http://technet.microsoft.com/en-us/library/cc730708(WS.10).aspx

Thanks!
 
B

bradbury9

This is for all the kind fellas that try to help me:

I found some advice to use ASP.NET Impersonation Authentication.
I started to do it (changed this property in the Web Service
Authentication configuration part in IIS7.5 to true) and changing the
Application pool to classic, but the web service did not load and gave
me an error.
I was affraid to continue and dive into this change, but is it the
correct direction?...

http://technet.microsoft.com/en-us/library/cc730708(WS.10).aspx

Thanks!

I prefer doing Impersonation changing the user of the application pool
intead of typing it at web.config file of the webservice. I dont like
typing passwords in plain text files.

Its quite strange that a .bat file executes code that cant be
imlemented using .NET. If you change it so it is not necessary using
the bat file it will be easier to mantain (just change the webservice
code) and you can debug what the lee the process is doing (you cannot
debug a bat file with Visual Studio)

If you really need to use the bat file:
Remember the adivce Marcell gave you about the /c parameter.
Make sure the user has read and execution right on c:\windows
\system32\cmd.exe (path could change depending on OS, that is winXP
path)
Make sure you got right also on file c:\file.bat

There are some limitations with web applications (and webservices) and
UI, they cannot display UI. You should see them at process list anyway.
 
D

dushkin

I prefer doing Impersonation changing the user of the application pool
intead of typing it at web.config file of the webservice. I dont like
typing passwords in plain text files.

Its quite strange that a .bat file executes code that cant be
imlemented using .NET. If you change it so it is not necessary using
the bat file it will be easier to mantain (just change the webservice
code) and you can debug what the lee the process is doing (you cannot
debug a bat file with Visual Studio)

If you really need to use the bat file:
Remember the adivce Marcell gave you about the /c parameter.
Make sure the user has read and execution right on c:\windows
\system32\cmd.exe (path could change depending on OS, that is winXP
path)
Make sure you got right also on file c:\file.bat

There are some limitations with web applications (and webservices) and
UI, they cannot display UI. You should see them at process list anyway.

As I mentioned on previous post - the batch file is not what I need.
It is only a test case. I also tried to open notepad and the
notepad.exe existed on the task manager list, but it was not shown "on
air".

From a console application the code I posted runs perfectly. There
must be I guess, some issues when running it from a web service. The
question is what are they...

At the end, I will need to use the Web service for running some
scripts.
 
D

dushkin

I prefer doing Impersonation changing the user of the application pool
intead of typing it at web.config file of the webservice. I dont like
typing passwords in plain text files.

Its quite strange that a .bat file executes code that cant be
imlemented using .NET. If you change it so it is not necessary using
the bat file it will be easier to mantain (just change the webservice
code) and you can debug what the lee the process is doing (you cannot
debug a bat file with Visual Studio)

If you really need to use the bat file:
Remember the adivce Marcell gave you about the /c parameter.
Make sure the user has read and execution right on c:\windows
\system32\cmd.exe (path could change depending on OS, that is winXP
path)
Make sure you got right also on file c:\file.bat

There are some limitations with web applications (and webservices) and
UI, they cannot display UI. You should see them at process list anyway.

Also, I did use the /C in my commanf arguments
Again, everything works well on a console application
 
D

dushkin

GOT IT GUYS!!!

I managed to get the error by using


p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardError = true;

string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();

Debug.WriteLine("output = " + output);
Debug.WriteLine("error = " + error);

and it told me that it cannot find the file to be copied.

So all I had to do is to set

p.StartInfo.WorkingDirectory = @"c:\stm";

and Hip hip Hurray!!!

Thank you all for your help!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top