I am trying to make a UI for some of the new Windows 10 Commands that have become useful to us. I am trying to make a UI that has three text boxes, one for the computer name, the username, and the message in order to utilize the msg command. When I run the command on my normal CMD, I would type msg /server:matthewl mlynch "hello",this will display a little message on my screen saying hello. However, when I try to run it from my c# ui, I get this
'msg' is not recognized as an internal or external command,
operable program or batch file.
As you can probably tell, this is not correct as it works when I launch command line and manually input but not when the UI runs the command.
Nevermind, coworker helped me, it was a setting in Project>Project Properties>Build>Platform Target and changed that to x64. Apparently it wasn't opening C:\Windows\System32, it was actually opening C:\Windows\Syswow64 but labeling itself as system32.
To run these commands, normally you'd use the System.Diagnostics.Process class to start the cmd.exe process, and then pass the command to the window:
Process.Start("cmd.exe",
$"/C msg /server:{txtServer.Text} {txtUser.Text} \"{txtMessage.Text}\"");
Related
I want to have my C# (Xamarin) program run an EXE or batch (BAT) file. The user will be running my program, and will click on one of several buttons, some of which open Web pages and others of which run external programs. These files will be on the same computer as the one running the main program and don't need greater permissions. The overall program will be in Windows, UWP.
I already have code to pull info from the database saying "the button the user clicked references a program and it's (eg) C:\Tools\MyTool.exe". (Real path more like (C:\Users\Me\source\repos\ProductNameV2\ProductName\ProductName.UWP\Assets\EXE\whatever.exe".) I used a "demo.bat" file containing nothing but echo and pause statements, or references to a built-in Windows program like Notepad or Calc that an ordinary command prompt can recognize without an explicit path (ie. that's part of the recognized system Path). Yes, the real path to the dummy file does exist; I checked. I've also explicitly added files demo.bat and dummy.txt to my C# project.
Here's roughly what I've tried so far to actually run a batch file, or an EXE, or just to try opening a text file. Nothing works.
1)
bool check = await Launcher.CanOpenAsync(#"file:///C:\Tools\demo.bat"); // Returns false.
bool check = await Launcher.CanOpenAsync(#"file:///C:\Tools\dummy.txt"); // Returns true.
await Launcher.OpenAsync(#"file:///C:\Tools\demo.bat") // Seems to do nothing; silently fails.
await Launcher.OpenAsync(#"file:///C:\Tools\dummy.txt") // Same.
2)
Process batchProcess = new Process();
batchProcess.StartInfo.FileName = #"file:///C:\Tools\demo.bat"; // Same result with notepad.exe
batchProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
batchProcess.Start();
batchProcess.WaitForExit();
// Result: "Access is denied" error during Start().
3)
var otherProcessInfo = new ProcessStartInfo(#"file:///C:\Tools\demo.bat")
var otherProcess = Process.Start(otherProcessInfo);
otherProcess.WaitForExit();
otherProcess.Close();
// Result: "The system cannot find the file specified" despite it being the same path as in previous examples.
// Also tried literally using the path C:\Tools\demo.bat, without adding that to the C# project.
// One thing that slightly works is to use:
var otherProcessInfo = new ProcessStartInfo("cmd.exe", "/c echo Hello world!");
// This version opens a window and instantly closes it again. With "/c pause" instead, it opens, saying "press any key to continue".
// Chaining multiple commands with newline or semicolon characters doesn't work as a form of batch file.
So: the only tiny success I've had here is to run cmd.exe, to run a one-line command. I suppose that depending on what the batch file must do, there's some possibility of receiving a string, breaking it into lines, then running cmd.exe using method 3 to call them one at a time. Which is ugly at best.
Is there some better way to do this -- to run a batch file or an EXE from within my program?
EDIT: Yes, I did in fact look at documentation before asking. Why did I use URIs? Because of multiple errors telling me that the simple path strings ("C:\this\that") I was using were in an "Invalid URI format". Using Process.Start("notepad.exe") silently fails, doing nothing. Using a method involving System.Diagnostics.Process (found at How to run external program via a C# program? and yes I saw that before) fails with an error of "Access denied" when using my batch file reference, or silently failing (no window opens) using plain old notepad.exe. I avoided setting Process options that say hide the window.
So to rephrase: Is there a way to make my program run some EXE somewhere on the computer, or to run a batch file that has more than one command in it? What is that way?
Using the data you collected, I was able to run a batch file by doing the following:
var strPathToExeOrBat = System.IO.Path.Combine("C:\\Tools", "demo.bat");
var otherProcessInfo = new ProcessStartInfo("cmd.exe", $"/c call \"{strPathToExeOrBat\"");
var otherProcess = Process.Start(otherProcessInfo);
otherProcess.WaitForExit();
otherProcess.Close();
I also think it would be helpful to review the capabilities of the cmd.exe application.
I found this post to be helpful:
https://stackoverflow.com/questions/515309/what-does-cmd-c-mean#:~:text=%2FC%20Carries%20out%20the%20command%20specified%20by%20the%20string%20and,switches%20by%20typing%20cmd%20%2F%3F%20.
In particular the /k option will leave the window open, if you don't want it to close after running a script.
Thank you very much for your question! It really helped me find the answer to this! (at least for my situation of a .NET MAUI windows app, but MAUI is built off of Xamarin.Forms, so you shouldn't have a problem doing the same thing)
EDIT: Updated to use file path from question and string interpolation with System.IO.Path.Combine for slightly greater cross platform capability
I've seen a very similar question asked before, here, however the answer thread fell apart. Basically, I installed Python (and checked the option to add to the Path variable), confirmed that it is indeed in the path variable (through the Environment Variables window like you would normally).
When opening a cmd window manually, I can type python -V and get the version back, and anything else really, and everything works fine, python is indeed exposed through the command prompt (when opened manually).
However, when I attempt to run a command through cmd.exe with a C# app I have, I get
'python' is not recognized as an internal or external command,
operable program or batch file.
The block of C# code I have
var proc = new Process();
var startInfo = new ProcessStartInfo
{
UseShellExecute = true,
FileName = "cmd.exe",
Arguments = "/K " + command
};
proc.StartInfo = startInfo;
proc.Start();
This has worked fine in the past. However I had my work machine upgraded to Windows 10 and have been struggling to get this working.
The command text hasn't changed since the application was working before my windows upgrade, and if I take it's text and run it through a manually opened command prompt it executes fine with no issues. So I'm hesitant to believe it's an issue with the command itself.
UPDATE: If I run echo %PATH% in a regular prompt I see python, if I run it in the command prompt my application opens, I do not. I tried using set PATH, but that didn't help. Why is it that the PATH variable is different between a command prompt I open manually and one my application opens?
I thought it might have something to do with User and System variables having their own path, but Python is in both of them when checked via System Properties, so I'm at a loss.
As a fun little project, I am trying to use C# to operate the bash.exe provided by Git. I want the process to behave just as if I ran it in the Git Bash Application. By this, I mean I want to be able to execute command and get the output of said commands (i.e. if I enter the command "curl --version", I want to get the same output as the image here and be able to store it in a variable)
I have come very close to accomplishing this with the code here. However, with some commands, I find that the Process in C# never terminates. For example, if I try to execute the command "curl --help", I find the the Process never exits where "curl --version" did. As a quick hack, I figured out that I could fix this by changing the command to
curl --help >> output.txt
and then reading the .txt file. This does cause the command to exit and to write the correct output to the file, however, I don't like having to do this and I am sure there is a better solution to make commands of this sort exit properly. Thanks for the help!
I am trying to execute a code from c# windows form application.
string cmdCode = "/C mogrify -crop 590x389+116+102! D:\\Backup\\Images\\*.TIF";
System.Diagnostics.Process.Start("CMD.exe", cmdCode);
But It doesnt do what it is supposed to do?
the code perfectly does the job when I type it in the command line. I already tried to change the path. I placed the tif files with MyApp.exe file and changed the cmdCode as
cmdCode = "/C mogrify -crop 590x389+116+102! *.TIF";
no success.. It shows up the black command promt very quickly and it gets disappeared.
I also tried to put the code in a file and make the extension .bat to run it but still no success!! any suggestions ?
Thanks
Try replacing the /C option with /K.
That will not solve your problem, but it should prevent the command prompt from disappearing, and allow you to see if any error is displayed by the prompt.
It's also possible that the PATH you are passing to CMD.exe is different from the one used by default, for some reason. Once you've started cmd.exe with the /K option, you should also be able to issue a echo %PATH% command, and see what you've got.
Remove the cmd.exe part and instead place there the path to mogrify.exe and start the parameters with "-crop...", removing the /C
If you're passing along path names that contain spaces you'll need to enclose the path with quotes, so the parameters will look like this:
"-crop \"590x389+116+102!\" \""+YourPathHere+"\"";
Okay, so I have a .net exe, and it runs when I type mono myexe.exe. However, if I want to use another command or close the terminal window the app stops executing.
I have tried using mono myexe.exe & and it runs and showing [8] 20078 etc., but once I type something else it shows [8]+ Stopped, and then executes the command I typed in.
Any ideas?
how about nohup mono myexe.exe &
If you want to use & then look into outputting the result to a file.
nohup mono program.exe > program.out &
The right way of doing this would be to create a daemon with your linux distro.
You can also run it as an service using this line of code:
mono-service -l:/tmp/myservice.lock ./ServiceDaemon.exe
where -l:LOCKFILE specifies the file to use for locking. When you look into your lock file, you will see the process id. The process id you can use to kill the service, whenever you need to terminate it.
Source: blog.chudinov.net