run shell command for third party application, pass file arguements - c#

I'm trying to edit my own shell command to include another shell command from another application, namely AxCrypt. In a sense I'm trying to merge two context menu actions into one. If I right-click on a file, I go to AxCrypt and choose "Encrypt file to .EXE". Then I right-click again on the encrypted file and choose my shell command.
The reason I'm being so specific is someone may have something like this already. I have added this:
try
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = true;
proc.StartInfo.FileName = #"C:\Program Files\Axantum\AxCrypt\AxCrypt.exe";
proc.Start();
MessageBox.Show("AxCrypt run");
}...
I get my messagebox, but the AxCrypt application doesn't run. any ideas on how to
determine if the executable i've entered is the right one for the context menu selection in windows
correctly run this process and feed it the file argument for the file that i clicked on (as if i had chosen their menu item from the context menu)
correctly word a message to send to AxCrypt on what i'm trying to do!

1. determine if the executable i've entered is the right one for the
context menu selection in windows
Run ProcessMonitor and check the path used to launch the exe is correct - otherwise you'll see whats wrong.
2. correctly run this process and feed it the file argument for the
file that i clicked on (as if i had chosen their menu item from the
context menu)
string args = String.Format(#"{0}", "A File Arg");
proc.StartInfo.Arguments = args;
3. correctly word a message to send to AxCrypt on what i'm trying to
do!
Send them a link to this SO Q & A

I had the same problem. Look this:
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
pProcess.StartInfo.FileName = #"C:\Users\Vitor\Documents\Visual Studio 2015\Projects\ConsoleApplication1\ConsoleApplication1\bin\Debug\ConsoleApplication1.exe";
pProcess.StartInfo.Arguments = "olaa";
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
pProcess.StartInfo.CreateNoWindow = true;
pProcess.Start();
string output = pProcess.StandardOutput.ReadToEnd();
pProcess.WaitForExit();

Related

how can I execute a shortcut(.lnk) using Process.Start()? [duplicate]

Is there a way to run an application via shortcut from a C# application?
I am attempting to run a .lnk from my C# application. The shortcut contains a significant number of arguments that I would prefer the application not have to remember.
Attempting to run a shortcut via Process.Start() causes an exception.
Win32Exception: The specified executable is not a valid Win32 application
This is the code I am using.
ProcessStartInfo info = new ProcessStartInfo ( "example.lnk" );
info.CreateNoWindow = true;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.RedirectStandardInput = true;
Process whatever = Process.Start( info );
Could you post some code. Something like this should work:
Process proc = new Process();
proc.StartInfo.FileName = #"c:\myShortcut.lnk";
proc.Start();
Setting UseShellExecute = false was the problem. Once I removed that, it stopped crashing.
if your file is EXE or another file type like ".exe" or ".mkv" or ".pdf" and you want run that with shortcut link your code must like this.
i want run "Translator.exe" program.
Process.Start(#"C:\Users\alireza\Desktop\Translator.exe.lnk");
If you're using UseShellExecute = false and trying to launch a batch file make sure to add .bat to the end of the filename. You don't need .bat if UseShellExecute = true though. This made me just waste an hour of work... hoping to save someone else.

Using a .R file as a resource and create a batch directly in C#

I have a number of shiny applications with the file structure global.R, ui.R, server.R and something I call batchTrigger.R. The contents of the latter is simply the following-
.libPath(*Path to my R Package Repository*)
require('shiny')
runApp(*Path to the folder with the aforementioned files*)
I created a batch file called application.cmd with the following code-
cls
#pushd ""
:::::::::::::::::::
#echo off
ECHO Loading...Please, wait. The Application will open automatically.
ECHO ---
ECHO Do not close this console window for the whole duration of your session
ECHO in the application.
ECHO ---
#echo off
"C:\Program Files\R\bin\Rscript.exe" ".../**batchTrigger.R**"
:::::::::::::::::::
#popd
cmd /k
This batch file is working just fine. Then I went one step further, and decided to create a windows form with multiple R Applications. I have two buttons in the form, each of which goes something like this-
private void application1_click(object sender, EventArgs e)
{
System.Diagnostics.Process cmd = new Process();
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.FileName = "...\\**application1.cmd**";
cmd.StartInfo.Arguments = "/K";
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.RedirectStandardInput = true;
cmd.Start();
}
So far, so good. Both the buttons work exactly as they were supposed to. I want to go one more step ahead, but since I am very new at C#, I need help. What I am hoping to get is a dynamic location for the R files and the cmd files within the thus deployed application, within the solution. In other words, I should be able to write the contents of the batch file within the C# code, and the path of the batchTrigger.R should be something which changes with the location of the windows form application (which will be a self contained deployed executable file). The idea is that the R package repository and R installation may remain static and can be pointed at by the batchTrigger.R and application.cmd respectively, but the location of batchTrigger.R itself along with other R files move with the application. I think that resource.resx can do something about this, but how exactly can I go about doing it, I don't seem to get. Any suggestion would be highly appreciated.
Make a general method:
private void StartSilentR(string rScriptFilePath)
{
System.Diagnostics.Process cmd = new Process();
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.FileName = #"C:\Program Files\R\bin\Rscript.exe";
cmd.StartInfo.Arguments = rScriptFilePath;
cmd.StartInfo.CreateNoWindow = false;
//avoid this unless you must control the app via stdin
//cmd.StartInfo.RedirectStandardInput = true;
cmd.Start();
}
Then write something that calls it after working out where the script is. For example if you have your directory structure as:
RLauncherCSharpApp.exe
rscripts\ui.R
rscripts\global.R
rscripts\batchTrigger.R
Then in c# you can:
//take exe Path, remove exe name and add rscripts folder and batchtrigger.R file name
var rbt = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "rscripts", "batchTrigger.R");
StartSilentR(rbt);
Or, say you want to search all the subfolders of the app's folder looking for all files called batchTrigger.R:
var exeFolder = Path.GetDirectoryName(Application.ExecutablePath);
string[] paths = Directory.GetFiles(exeFolder, "batchTrigger.R", SearchOption.AllDirectories);
//maybe add them to a list view and the user can click one to launch ..

C# System.Diagnostics.Process how to handle multiple batch files

I'm trying to start tomcat from my c# wpf app using the startup.bat and after deploying the war files, I want to close it. Here is how I've been doing it and it seemed to work fine.
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = Tomcat_DIR_tbox.Text + #"\bin\startup.bat";
proc.StartInfo.WorkingDirectory = Tomcat_DIR_tbox.Text + #"\bin\";
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
// do some bla bla
//Close Tomcat
proc.StartInfo.Filename = Tomcat_DIR_tbox.Text + #"\bin\shutdown.bat";
proc.Start();
proc.WaitForExit();
Now I've been thinking that although it works, it's not quite right ? the Tomcat application started never stops unless I tell it to, it feels wrong to use the same process to also shut it down ?
What I've down now is something like this : Kept the process for starting up tomcat, and created another one which calls for the shutdown:
//Close tomcat
System.Diagnostics.Process proc_shutdown = new System.Diagnostics.Process();
proc_shutdown.StartInfo.WorkingDirectory = Tomcat_DIR_tbox.Text + #"\bin\";
proc_shutdown.StartInfo.FileName = Tomcat_DIR_tbox.Text + #"\bin\shutdown.bat";
proc_shutdown.StartInfo.CreateNoWindow = true;
proc_shutdown.Start();
proc_shutdown.WaitForExit();
The only thing I don't like about this method is that it brings a message which asks me if I allow the shutdown.bat to be called from my application, which I can uncheck "Don't ask me again for this file" but I still don't like the user experience it provides.
I also tried calling directly proc.Close() instead of doing proc.Filename = path_to_shutdown and proc.Start(), but it seemed to hang up my application and never close tomcat.
So what is the best way to start tomcat, do some stuff and then close it up ? Thanks , Razvan.
Based on my observation, what you are doing is fine to start and stop the tomcat server from WPF application. But, if you want to hide the security warning, Then Open Internet Explorer Go to Tools -> Internet Options and then select "security" tab from there select (Custom level..).. In that in the Miscellaneous group there will be option called
"Launching Applications and Unsafe files" -> Select Enable Radio button. Then it won't show you the "allow the shutdown.bat" popup.
Hope, it helps.

Programmatically setting startin location when starting a process

I have an application that creates a shortcut on my desktop and allows you to drag and drop files into the shortcut to perform an action (convert a word document to PDF). Now what I am trying to do is perform this action programmatically using shellexecute (.NET Process.Start()).
The problem is that it doesnt seem to be working and I have a sneaking suspicion this has something to do with the fact that the shortcut created has the "Start in" parameter set to a specific folder.
So it looks like this:
Shortcut target: "C:\Program Files (x86)\MyPDFConvertor\MyPDFConvertor.exe"
Shortcut startin: "C:\Program Files (x86)\MyPDFConvertor\SomeSubfolder\SomeSubSubFolder"
My code was the following.
System.Diagnostics.Process.Start("C:\\Program Files (x86)\\MyPDFConvertor\\MyPDFConvertor.exe", "C:\\MyFiles\\This is a test word document.docx");
Fundamentally my question boils down to: What does "Startin" actually mean/do for shortcuts and can I replicate this functionality when starting an application using either shellexecute or Process.Start?
When you use Process.Start you can call it with a ProcessStartInfo which in turn happens to be able to setup a WorkingDirectory property - this way you can replicate that behaviour.
As Yahia said, set the WorkingDirectory property. You also need to quote the arguments. Here is a rough example:
//System.Diagnostics.Process.Start("C:\\Program Files (x86)\\MyPDFConvertor\\MyPDFConvertor.exe", "C:\\MyFiles\\This is a test word document.docx");
ProcessStartInfo start = new ProcessStartInfo();
//must exist, and be fully qualified:
start.FileName = Path.GetFullPath("C:\\Program Files (x86)\\MyPDFConvertor\\MyPDFConvertor.exe");
//set working directory:
start.WorkingDirectory = Path.GetFullPath("C:\Program Files (x86)\MyPDFConvertor\SomeSubfolder\SomeSubSubFolder");
//arguments must be quoted:
const char quote = '"';
start.Arguments = quote + "C:\\MyFiles\\This is a test word document.docx" + quote;
//disable the error dialog
start.ErrorDialog = false;
try
{
Process process = Process.Start(start);
if(process == null)
{//started but we don't have access
}
else
{
process.WaitForExit();
int exitCode = process.ExitCode;
}
}
catch
{
Console.WriteLine("failed to start the program.");
}

Mimic Windows' 'Run' window in .NET

I would like to mimic the Run command in Windows in my program. In other words, I would like to give the user the ability to "run" an arbitrary piece of text exactly as would happen if they typed it into the run box.
While System.Diagnostics.Process.Start() gets me close, I can't seem to get certain things like environment variables such as %AppData% working. I just keep getting the message "Windows cannot find '%AppData%'..."
You can use the Environment.ExpandEnvironmentVariables method to turn %AppData% into whatever it actually corresponds to.
Depending on what you're trying to do, you could also call CMD.EXE, which will expand your environment variables automatically. The example below will do a DIR of your %appdata% folder, and redirect the stdOut to the debug:
StreamReader stdOut;
Process proc1 = new Process();
ProcessStartInfo psi = new ProcessStartInfo("CMD.EXE", "/C dir %appdata%");
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
proc1.StartInfo = psi;
proc1.Start();
stdOut = proc1.StandardOutput;
System.Diagnostics.Debug.Write(stdOut.ReadToEnd());

Categories