Is there a way to conect the input/output of a console application to the output/input of another program - input

I have an application i cannot edit that reads from the console and writes to it and i want to know how i can read what the program is saying and write back commands to the program.
This is for a minecraft server where i want to read what the players are saying and run commands acoording to what is said. (the server is the application i cannot edit)
I cannot create a modification for the server, because i am using a mod that checks if there are any other modifications done to the files and fails to load if that is the case.

I wrote a simple app in c# to get started with, to redirect the I/O streams you need to start the application (in this case the server) within your own application.
First we create a new instance of the System.Diagnostics.Process class
var process = new Process();
then we specify the start info
process.StartInfo = new ProcessStartInfo
{
FileName = Console.ReadLine(), //Reads executable path from console
RedirectStandardOutput = true,
RedirectStandardInput = true,
UseShellExecute = false
};
then we add an event handler, in this example it's just writes the lines with a "> " prefix
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine($"> {e.Data}");
and now we can start the process by calling Process#Start()
process.Start();
and finally we can call Process#BeginOutputReadLine() without this the OutputDataReceived event will never trigger
process.BeginOutputReadLine();
To send commands you can use the process' StandardInput stream
process.StandardInput.WriteLine("command");
The fully working code with example output (tested with cmd.exe, but it's must work with MC servers)
Code:
static void Main(string[] args)
{
Console.Write("Enter executable path: ");
var process = new Process();
process.StartInfo = new ProcessStartInfo
{
FileName = Console.ReadLine(), //Reads executable path, for example cmd is the input
RedirectStandardOutput = true,
RedirectStandardInput = true,
UseShellExecute = false
};
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => Console.WriteLine($"> {e.Data}");
process.Start();
process.BeginOutputReadLine();
process.StandardInput.WriteLine("echo a");
//Prevent closing
Console.ReadKey();
}
Output:
Enter executable path: cmd
> Microsoft Windows [Version 10.0.18362.239]
> (c) 2019 Microsoft Corporation. Minden jog fenntartva.
>
> F:\VisualStudio\StackOverflow\StackOverflow\bin\Debug\netcoreapp2.1>echo a
> a
>

Related

Execute SSH command line with sudo and enter password afterward [duplicate]

I am trying to use Renci SSH.NET to connect to a remote Linux server from a C# web application and execute shell scripts. I want to run the scripts one after another. But not getting how to run the scripts and read the output and store it in a label.
I have tried the below code, but not able to pass multiple commands one line after another.
SshClient sshclient = new SshClient("host", UserName, Password);
sshclient.Connect();
ShellStream stream = sshclient.CreateShellStream("commands", 80, 24, 800, 600, 1024);
public StringBuilder sendCommand(string customCMD)
{
StringBuilder answer;
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
writer.AutoFlush = true;
WriteStream(customCMD, writer, stream);
answer = ReadStream(reader);
return answer;
}
private void WriteStream(string cmd, StreamWriter writer, ShellStream stream)
{
writer.WriteLine(cmd);
while (stream.Length == 0)
{
Thread.Sleep(500);
}
}
private StringBuilder ReadStream(StreamReader reader)
{
StringBuilder result = new StringBuilder();
string line;
while ((line = reader.ReadLine()) != null)
{
result.AppendLine(line);
}
return result;
}
I am trying to run the below commands
sudo su - wwabc11
whoami
cd /wwabc11/batch/bin/
pwd
How to run the commands one after another and read the output information? Thanks.
Just write the "commands" to the StreamWriter.
writer.WriteLine("sudo su - wwabc11");
writer.WriteLine("whoami");
// etc
See also C# send Ctrl+Y over SSH.NET.
Though note that using CreateShellStream ("shell" channel) is not the correct way to automate a commands execution. You should use CreateCommand/RunCommand ("exec" channel). Though SSH.NET limited API to the "exec" channel does not support providing an input to commands executed this way. And whoami and the others are actually inputs to sudo/su command.
A solution would be to provide the commands to su on its command-line, like:
sudo su - wwabc11 -c "whoami ; cd /wwabc11/batch/bin/ ; pwd"
For an example of code that uses CreateCommand to execute a command and reads its output, see see SSH.NET real-time command output monitoring.

Executable app(.exe) not running via the ASP.Net Webservice(.asmx)

I want to execute a process from the ASP.Net Webservice(.asmx).
In the Webservice hosted directory, I have a executable app in "importerapp" folder of the webservice directory. My executable app is ( Named as Import.exe) is working good by double clicking.
My webservice is running with no error but the process is not executed.
[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public string executeProcess(RunMode mode )
{
Process process = new Process();
process.StartInfo.FileName = Server.MapPath("importerapp/Import.exe");
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.Arguments = "mode=" + (int)_runMode ;
process.Start();
process.WaitForExit();
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
return("Job Submitted OK with params: "+_runMode + error
+ output +"Exit Code:"+ process.ExitCode );
}
In the browser, The output is as below.
<string xmlns="http://tempuri.org/">Job Submitted OK with
params: Exit Code:0</string>
That means, the "error" and "output" variable is null and exit code is 0 which means success.
But the processing is not doing anything, even not creating logfile( I am using nLog library).
Environment: WIndows7, IIS 7.5, .Net4.0, C#, ASP.Net
Please advise.
Thanks.
Ruhul
Job Submitted OK with params: Exit Code:0
This, according to your code, means that _runMode variable is not initiated. I think you forget to pass the parameter mode to your process

How can I get the alternates of SAPI speech recognization result

On windows7 platform I can use System.Speech.Recognition.SpeechRecognitionEngine to convert voice to text.By SpeechRecognitionEngine when the SpeechRecognized event triggered I can get some alternate words,and I can show these word to users for choise.
void engine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (this.SpeechRecognized != null)
{
this.SpeechRecognized(this, new RecognizedResultEventArgs
{
Text = e.Result.Text,
Alternates = new ReadOnlyCollection<string>(e.Result.Alternates.Select(p => p.Text).ToList())
});
}
}
By the way,when I initialise SpeechRecognitionEngine instance,I want to load some specifical word instead of use "DictationGrammar".
My program need to runing on xp platform sometimes.So I want to implament a specific vertion to run on xp operating system by use sapi5.1.
I have readed a portion of sapi 5.1 document,then I get that:in sapi5.1,I can use "command and control" way to do that. but the "Result.Alternates()" method can not be used when I use "command and control".So,how can I achieve the same effect of SpeechRecognitionEngine ?
I tried the following code and there is an com Eception:
public void RecoContext_Recognition(int StreamNumber, object StreamPosition, SpeechRecognitionType RecognitionType, ISpeechRecoResult Result)
{
ISpeechPhraseProperty oItem;
oItem = Result.PhraseInfo.Properties.Item(0);
if ((System.Decimal)Result.PhraseInfo.GrammarId == grammarId)
{
if (this.SpeechRecognized != null)
{
RecognizedResultEventArgs e = new RecognizedResultEventArgs();
e.Text = oItem.Name;
// The following code throws an exception
ISpeechPhraseAlternates alternates = Result.Alternates(10);
List<string> s = new List<string>();
foreach (ISpeechPhraseAlternate item in alternates)
{
s.Add(item.RecoResult.PhraseInfo.Properties.Item(0).Name);
}
e.Alternates = new ReadOnlyCollection<string>(s);
this.SpeechRecognized(this, e);
}
}
}
Is there any way to get the alternates by use sapi by way of COM?Thank you.
In SAPI (any version), command and control grammars don't have alternates. Only dictation grammars have alternates.

How can I read custom action's executable output in WiX?

I'm making MSI installer in WiX. During installation I want to run an executable from a custom action and get its standard output (not the return code) for later use during installation (with Property element, supposedly).
How can I achieve it in WiX (3.5)?
I used this code for a similar task (its a C# DTF custom action):
// your process data
ProcessStartInfo processInfo = new ProcessStartInfo() {
CreateNoWindow = true,
LoadUserProfile = true,
UseShellExecute = false,
RedirectStandardOutput = true,
StandardOutputEncoding = Encoding.UTF8,
...
};
Process process = new Process();
process.StartInfo = processInfo;
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) =>
{
if (!string.IsNullOrEmpty(e.Data) && session != null)
{
// HERE GOES THE TRICK!
Record record = new Record(1);
record.SetString(1, e.Data);
session.Message(InstallMessage.ActionData, record);
}
};
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
if (process.ExitCode != 0) {
throw new Exception("Execution failed (" + processInfo.FileName + " " + processInfo.Arguments + "). Code: " + process.ExitCode);
}
process.Close();
This is called "screen scraping" and while it's technically possible to create the infrastructure to run an EXE out of process, scrape it's output and then marshal the data back into the MSI context, it'll never be a robust solution.
A better solution would be to understand what the EXE does and how it does it. Then write a C# o C++ custom action that runs in process with access to the MSI handle so that you can do the work and set the properties you need to set.

ClickOnce application won't accept command-line arguments

I have a VB.NET application that takes command-line arguments.
It works fine when debugging provided I turn off Visual Studio's ClickOnce security setting.
The problem occurs when I try to install the application on a computer via ClickOnce and try to run it with arguments. I get a crash when that happens (oh noes!).
There is a workaround for this issue: move the files from the latest version's publish folder to a computer's C: drive and remove the ".deploy" from the .exe. Run the application from the C: drive and it will handle arguments just fine.
Is there a better way to get this to work than the workaround I have above?
Thanks!
"Command-line arguments" only work with a ClickOnce app when it is run from a URL.
For example, this is how you should launch your application in order to attach some run-time arguments:
http://myserver/install/MyApplication.application?argument1=value1&argument2=value2
I have the following C# code that I use to parse ClickOnce activation URL's and command-line arguments alike:
public static string[] GetArguments()
{
var commandLineArgs = new List<string>();
string startupUrl = String.Empty;
if (ApplicationDeployment.IsNetworkDeployed &&
ApplicationDeployment.CurrentDeployment.ActivationUri != null)
{
// Add the EXE name at the front
commandLineArgs.Add(Environment.GetCommandLineArgs()[0]);
// Get the query portion of the URI, also decode out any escaped sequences
startupUrl = ApplicationDeployment.CurrentDeployment.ActivationUri.ToString();
var query = ApplicationDeployment.CurrentDeployment.ActivationUri.Query;
if (!string.IsNullOrEmpty(query) && query.StartsWith("?"))
{
// Split by the ampersands, a append a "-" for use with splitting functions
string[] arguments = query.Substring(1).Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries).Select(a => String.Format("-{0}", HttpUtility.UrlDecode(a))).ToArray();
// Now add the parsed argument components
commandLineArgs.AddRange(arguments);
}
}
else
{
commandLineArgs = Environment.GetCommandLineArgs().ToList();
}
// Also tack on any activation args at the back
var activationArgs = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
if (activationArgs != null && activationArgs.ActivationData.EmptyIfNull().Any())
{
commandLineArgs.AddRange(activationArgs.ActivationData.Where(d => d != startupUrl).Select((s, i) => String.Format("-in{1}:\"{0}\"", s, i == 0 ? String.Empty : i.ToString())));
}
return commandLineArgs.ToArray();
}
Such that my main function looks like:
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
var commandLine = GetArguments();
var args = commandLine.ParseArgs();
// Run app
}