Process.start environment path - c#

I have console application 1 which write text to file and it is in C:/app1
using (StreamWriter k = new StreamWriter("777.txt"))
k.WriteLine("aa");
I have another console application 2, c:/app2, which start console application 1
System.Diagnostics.Process.Start("c:/app1/app1.exe");
For some reason, when I run application 2, the output 777.txt will be in folder2 instead of folder1. When I run application 1 from windows explorer, the output 777.txt will be in folder1.
I look and tried to add environment.path but it didn't solve the problem.

Please try the following:
ProcessStartInfo startInfo = new ProcessStartInfo(#"c:\app1\app1.exe");
startInfo.WorkingDirectory= #"c:\app1";
Process.Start(startInfo);

Your application 1 is using a relative path, not a rooted path. That path is relative to the "current directory", not the "path" environment variable.
Process can accept a ProcessStartInfo instance which includes a property to define the current directory. You'll want to set that to the location of application 1 before starting it.

you should replace your "777.txt" with AppDomain.CurrentDomain.BaseDirectory & "777.txt"

Related

Shell Script File(.sh) does not run from c# core on linux

I am trying to run ".sh" file from c# core application.But it doesn't seem to be running properly.Here is my scenario.
I am working on .Net core project which is hosted on Linux environment.We are trying to create "PDF" in our project for which we have used "Apache FOP".
Here i have created one "shell script" file "transform.sh" which internally calls "fop" with required parameters.Since developement is being done on windows machine we tested the same usinf "batch" file i.e. "transform.bat",but since we cannot use the "batch" file on linux enviornment we have created shell script file "transform.sh"
Following is the code from"transform.sh"
./fop -xml $1 -xsl $2 -pdf $3
Following is C# code from which i am calling the "shell script file
var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
RedirectStandardOutput = true,
Arguments = string.Format("{0} {1} {2}", XML_filename, XSL_filename, output)
}
};
process.StartInfo.FileName = "Path to shell script file";
process.Start();
process.WaitForExit();
Above code doesnot give any error but it also does not create the pdf file.If i directly run the shell script file from "Terminal" it works fine and create pdf file.
./transform.sh "/home/ubuntu/psa//PdfGeneration/ApacheFolder/XMLFolder/test.xml" "/home/ubuntu/psa/PdfGeneration/ApacheFolder/XSLTFolder/Certificate.xsl" "/home/ubuntu/psa/PdfGeneration/ApacheFolder/PDFFolder/t444t.pdf"
Please let me know if there is something wrong i am doing?How can i make the sheel script run on linux through C# core application.
Thanks.
I was able to solve the issue,just thought that i should put my solution here so that it may help others in future...
As mentioned in Question i was not able to generate the PDF file through shell script on linux machine.After debugging as suggested by "#JNevill" I came to understand that the shell script file was not getting called from .net process itself.
So my first task was to make the shell script file called through .Net Process.
After lots of searching through Net and trying out different solutions i got solution at How to perform command in terminal using C#(Mono).
So changed my code of calling the process as follow,
var command = "sh";
var myBatchFile = //Path to shell script file
var argss = $"{myBatchFile} {xmlPath} {xsltPath} {pdfPath}"; //this would become "/home/ubuntu/psa/PdfGeneration/ApacheFolder/ApacheFOP/transform.sh /home/ubuntu/psa/PdfGeneration/ApacheFolder/XMLFolder/test.xml /home/ubuntu/psa/PdfGeneration/ApacheFolder/XSLTFolder/Certificate.xsl /home/ubuntu/psa/PdfGeneration/ApacheFolder/PDFFolder/test.pdf"
var processInfo = new ProcessStartInfo();
processInfo.UseShellExecute = false;
processInfo.FileName = command; // 'sh' for bash
processInfo.Arguments = argss; // The Script name
process = Process.Start(processInfo); // Start that process.
var outPut = process.StandardOutput.ReadToEnd();
process.WaitForExit();
After changing the code ,the ".sh" file got executed and i was able to generate the PDF file.
Also script of the ".sh" file i.e. (transform.sh) which was calling Apache FOP file i.e. "FOP.sh" also needed to be changed.
Initially code was
./fop -xml $1 -xsl $2 -pdf $3
Which i changed as follow,(Change was to give full path of the FOP file)
/home/ubuntu/psa/PdfGeneration/ApacheFolder/ApacheFOP/fop -xml $1 -xsl $2 -pdf $3
Late answer, but for me, it worked just by setting the RedirectStandardOutput to true and changing the FileName property like this:
processInfo.FileName = #"C:\Program Files\Git\git-bash.exe";
processInfo.RedirectStandardOutput = true;

How can I set the AppData folder for a new process?

I would like to start a new process but I need it to use a different folder for AppData. In a windows batch file you can do it like this:
set APPDATA=C:\MyDataFolder
It will set the AppData for any program launched in the batch file, so how can I do this in C#?
You can add environment variables to the ProcessStartInfo:
ProcessStartInfo p = new ProcessStartInfo("some_executable.exe");
p.UseShellExecute = false; // apparently required when adding environment variables
p.EnvironmentVariables.Add("APPDATA", #"C:\MyDataFolder");
Process.Start(p);
Off the top of my head: Environment.SetEnvironmentVariable
According to MSDN:
Creates, modifies, or deletes an environment variable stored in the
current process.
Current process being the operative word...

Launch Program with Parameters

How do I write a very simple program that uses the command line to navigate to a program in the user's Program Files directory, then launches the .exe with a parameter? For example:
"C:\etc\Program Files\ProgramFolder\Program.exe C:\etc\desktop\file.spp C\etc\desktop\file.txt"
This launches a program with a certain project file and a .txt file along with it.
You can use the ProcessStartInfo.Arguments property to specify the string of arguments for your program:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\etc\Program Files\ProgramFolder\Program.exe";
startInfo.Arguments = #"C:\etc\desktop\file.spp C:\etc\desktop\file.txt";
Process.Start(startInfo);
Just create a new text file, name it "go.cmd" and put the following in there:
"C:\etc\Program Files\ProgramFolder\Program.exe C:\etc\desktop\file.spp C\etc\desktop\file.txt"
Voila, you have your program!
if you want to pass full executable path and parameters the program you need is the windows command prompt.

Error in Process.Start() -- The system cannot find the file specified

I am using the following code to fire the iexplore process. This is done in a simple console app.
public static void StartIExplorer()
{
var info = new ProcessStartInfo("iexplore");
info.UseShellExecute = false;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
string password = "password";
SecureString securePassword = new SecureString();
for (int i = 0; i < password.Length; i++)
securePassword.AppendChar(Convert.ToChar(password[i]));
info.UserName = "userName";
info.Password = securePassword;
info.Domain = "domain";
try
{
Process.Start(info);
}
catch (System.ComponentModel.Win32Exception ex)
{
Console.WriteLine(ex.Message);
}
}
The above code is throwing the error The system cannot find the file specified. The same code when run without specifying the user credentials works fine. I am not sure why it is throwing this error.
Can someone please explain?
Try to replace your initialization code with:
ProcessStartInfo info
= new ProcessStartInfo(#"C:\Program Files\Internet Explorer\iexplore.exe");
Using non full filepath on Process.Start only works if the file is found in System32 folder.
You can't use a filename like iexplore by itself because the path to internet explorer isn't listed in the PATH environment variable for the system or user.
However any path entered into the PATH environment variable allows you to use just the file name to execute it.
System32 isn't special in this regard as any directory can be added to the PATH variable. Each path is simply delimited by a semi-colon.
For example I have c:\ffmpeg\bin\ and c:\nmap\bin\ in my path environment variable, so I can do things like new ProcessStartInfo("nmap", "-foo") or new ProcessStartInfo("ffplay", "-bar")
The actual PATH variable looks like this on my machine.
%SystemRoot%\system32;C:\FFPlay\bin;C:\nmap\bin;
As you can see you can use other system variables, such as %SystemRoot% to build and construct paths in the environment variable.
So - if you add a path like "%PROGRAMFILES%\Internet Explorer;" to your PATH variable you will be able to use ProcessStartInfo("iexplore");
If you don't want to alter your PATH then simply use a system variable such as %PROGRAMFILES% or %SystemRoot% and then expand it when needed in code. i.e.
string path = Environment.ExpandEnvironmentVariables(
#"%PROGRAMFILES%\Internet Explorer\iexplore.exe");
var info = new ProcessStartInfo(path);
Also, if your PATH's dir is enclosed in quotes, it will work from the command prompt but you'll get the same error message
I.e. this causes an issue with Process.Start() not finding your exe:
PATH="C:\my program\bin";c:\windows\system32
Maybe it helps someone.
I had the same problem, but none of the solutions worked for me, because the message The system cannot find the file specified can be misleading in some special cases.
In my case, I use Notepad++ in combination with the registry redirect for notepad.exe. Unfortunately my path to Notepad++ in the registry was wrong.
So in fact the message The system cannot find the file specified was telling me, that it cannot find the application (Notepad++) associated with the file type(*.txt), not the file itself.
I know it's a bit old and although this question have accepted an answer, but I think its not quite answer.
Assume we want to run a process here C:\Program Files\SomeWhere\SomeProcess.exe.
One way could be to hard code absolute path:
new ProcessStartInfo(#"C:\Program Files\SomeWhere\SomeProcess.exe")
Another way (recommended one) is to use only process name:
new ProcessStartInfo("SomeProcess.exe")
The second way needs the process directory to be registered in Environment Variable Path variable. Make sure to add it in System Variables instead of Current User Variables, this allows your app to access this variable.
You can use the folowing to get the full path to your program like this:
Environment.CurrentDirectory

.NET Process.Start default directory?

I'm firing off a Java application from inside of a C# .NET console application. It works fine for the case where the Java application doesn't care what the "default" directory is, but fails for a Java application that only searches the current directory for support files.
Is there a process parameter that can be set to specify the default directory that a process is started in?
Yes!
ProcessStartInfo Has a property called WorkingDirectory, just use:
...
using System.Diagnostics;
...
var startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = // working directory
// set additional properties
Process proc = Process.Start(startInfo);
Use the ProcessStartInfo.WorkingDirectory property to set it prior to starting the process. If the property is not set, the default working directory is %SYSTEMROOT%\system32.
You can determine the value of %SYSTEMROOT% by using:
string _systemRoot = Environment.GetEnvironmentVariable("SYSTEMROOT");
Here is some sample code that opens Notepad.exe with a working directory of %ProgramFiles%:
...
using System.Diagnostics;
...
ProcessStartInfo _processStartInfo = new ProcessStartInfo();
_processStartInfo.WorkingDirectory = #"%ProgramFiles%";
_processStartInfo.FileName = #"Notepad.exe";
_processStartInfo.Arguments = "test.txt";
_processStartInfo.CreateNoWindow = true;
Process myProcess = Process.Start(_processStartInfo);
There is also an Environment variable that controls the current working directory for your process that you can access directly through the Environment.CurrentDirectory property .
Just a note after hitting my head trying to implement this.
Setting the WorkingDirectory value does not work if you have "UseShellExecute" set to false.
Use the ProcessStartInfo.WorkingDirectory property.
Docs here.
The Process.Start method has an overload that takes an instance of ProcessStartInfo. This class has a property called "WorkingDirectory".
Set that property to the folder you want to use and that should make it start up in the correct folder.
Use the ProcessStartInfo class and assign a value to the WorkingDirectory property.

Categories