I'm running an external exe from a C# windows application. The exe is an console window and i pass initial command line arguments "a and b" like this
Process p = new Process();
p.StartInfo.FileName = "something.exe";
p.StartInfo.Arguments = "a b";
p.Start();
p.WaitForExit();
p.Close();
Now i need to pass the second arguments in the same exe that is the application "something.exe" starts execution with the initial arguments a and b and then it further needs some inputs c and d in the next step. How can i give the second input c and d in the C# application. Please provide me a solution.
Got it guys
Process p = new Process();
p.StartInfo.FileName = "something.exe";
p.StartInfo.Arguments = "a b";
**p.StartInfo.UseShellExecute = false;**
**p.StartInfo.RedirectStandardInput = true;**
p.Start();
**p.StandardInput.WriteLine("c");**
**p.StandardInput.WriteLine("d");**
p.WaitForExit();
p.Close();
Related
I am trying to launch an application in a new console window from a FAKE script.
In normal .NET code, the method System.Diagnostics.Process.Start can be used to do this.
I've also done this in the past with CAKE, like this:
Task("run-myapp")
.Does(() => {
var info = new ProcessStartInfo {
FileName = "dotnet",
Arguments = "run myapp.fsproj",
WorkingDirectory = "C:\\path\\to\\my\\app\\"
};
Process.Start(info);
});
In FAKE, I have tried the same thing, but this starts a new background process and outputs to the console window where I run FAKE. I then later need to use Task Manager to kill that process.
Target.create "run-myapp" (fun _ ->
let psi = ProcessStartInfo()
psi.FileName <- "dotnet"
psi.Arguments <- "run myapp.fsproj"
psi.WorkingDirectory <- "C:\\path\\to\\my\\app\\"
Process.Start psi |> ignore
)
I have also tried explicitly setting ProcessStartInfo.CreateNoWindow <- false (although false is the default) and this does not change anything.
Is there a way to do this in FAKE?
I found the answer in the issue on this closed GitHub issue: https://github.com/dotnet/corefx/issues/21767#issuecomment-312328630
The reason is the default value of UseShellExecute is false in .NET Framework, but true in .NET Core. CAKE is in Framework and FAKE 5 is in Core.
Solution:
Target.create "run-myapp" (fun _ ->
let psi = ProcessStartInfo()
psi.FileName <- "dotnet"
psi.Arguments <- "run myapp.fsproj"
psi.WorkingDirectory <- "C:\\path\\to\\my\\app\\"
psi.UseShellExecute <- true
Process.Start psi |> ignore
)
I use powershell to invoke a sql stored procedure, now I want to redirect the complete set of the output into a .ps1 file, because the the output line is executable in powershell.
I'm trying to use >output.ps1, it works, but I'm checking the output file, it contains a lot of '...' to replace real output.
How to export the complete output? also stripe the header off?
Thanks.
It depends how you invoke the stored procedure. If you're invoking it within PowerShell, you should be able to collect the output, so I assume you're starting it as a separate task its own window. Without your actual example, here's a way to collect the output from the tasklist.exe command. You may find it applicable.
cls
$exe = 'c:\Windows\System32\tasklist.exe'
$processArgs = '/NH'
try {
Write-Host ("Launching '$exe $processArgs'")
$info = New-Object System.Diagnostics.ProcessStartInfo
$info.UseShellExecute = $false
$info.RedirectStandardError = $true
$info.RedirectStandardOutput = $true
$info.RedirectStandardInput = $true
$info.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
$info.CreateNoWindow = $true
$info.ErrorDialog = $false
$info.WorkingDirectory = $workingDir
$info.Filename = $exe
$info.Arguments = $processArgs
$process = [System.Diagnostics.Process]::Start($info)
Write-Host ("Launched $($process.Id) at $(Get-Date)")
<#
$process.StandardOutput.ReadToEnd() is a synchronous read. You cannot sync read both output and error streams.
$process.BeginOutputReadLine() is an async read. You can do as many of these as you'd like.
Either way, you must finish reading before calling $process.WaitForExit()
http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx
#>
$output = $process.StandardOutput.ReadToEnd()
$process.WaitForExit() | Out-Null
Write-Host ("Exited at $(Get-Date)`n$output")
} catch {
Write-Host ("Failed to launch '$exe $processArgs'")
Write-Host ("Failure due to $_")
}
$output
I'm new on MVC!
I want to run a process on my web app (not for bad purpose), this process can do something, for example it can write a text to a file .txt!
On my local PC, it work well but when I publish it on to host provider, it not work!
How I can do this?
This is my code:
string path = HttpContext.Current.Server.MapPath("~/App_Data/ModuleMaple/ModuleMaple.exe");
Process myproc = new Process();
myproc.StartInfo.FileName = path;
myproc.StartInfo.Arguments ="some argument"
myproc.StartInfo.UseShellExecute = false;
myproc.Start();
myproc.WaitForExit();
I was going through one of Don Syme's blog posts Async and Parallel Design Patterns in F#: Agents. However, the following seemingly extremely simple code did not generate output as expected.
type Agent<'T> = MailboxProcessor<'T>
let agent =
Agent.Start(fun inbox ->
async { while true do
let! msg = inbox.Receive()
printfn "got message '%s'" msg } )
for i in 1 .. 10000 do
agent.Post (sprintf "message %d" i)
Instead of expected 10,000 messages , I only got something around 3000 messages using Mono 2.8.1 under Ubuntu, or 15 messages using Visual F# under Windows XP. Am I missing anything here? BTW, I tried to replace the printfn statement with the following File op and ended up with same partial results.
open System.IO
type Agent<'T> = MailboxProcessor<'T>
let agent =
Agent.Start(fun inbox ->
async { while true do
let! msg = inbox.Receive()
use logger = new StreamWriter("a.log", true)
logger.WriteLine("got message '{0}'", msg.ToString())
logger.Close()
} )
for i in 1 .. 10000 do
agent.Post (sprintf "message %d" i)
Just run your code in Win machine - everything is OK. Try to add
ignore( System.Console.ReadKey() )
as a last line, because agent.Post is non-blocking and after posting 10000 messages control flow will move forward, possibly exiting the program.
I am new to F#. I am trying to communicate with java from F# using named pipe. The code below works but I am not sure if there is a better way to do this (I know the infinite loop is a bad idea but this is just a proof of concept) if anyone have any idea to improve this code please post your comments.
Thanks in advance
Sudaly
open System.IO
open System.IO.Pipes
exception OuterError of string
let continueLooping = true
while continueLooping do
let pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4)
printfn "[F#] NamedPipeServerStream thread created."
//wait for connection
printfn "[F#] Wait for a client to connect"
pipeServer.WaitForConnection()
printfn "[F#] Client connected."
try
// Stream for the request.
let sr = new StreamReader(pipeServer)
// Stream for the response.
let sw = new StreamWriter(pipeServer)
sw.AutoFlush <- true;
// Read request from the stream.
let echo = sr.ReadLine();
printfn "[F#] Request message: %s" echo
// Write response to the stream.
sw.WriteLine("[F#]: " + echo)
pipeServer.Disconnect()
with
| OuterError(str) -> printfn "[F#]ERROR: %s" str
printfn "[F#] Client Closing."
pipeServer.Close()
Well, it doesn't look like anything is throwing OuterError, so I would remove that exception type and unused handling.
I am unsure about your experience level or what type of "better" you are looking for. You way want to read F# async on the server to learn more about async and avoiding blocking threads.
Below you can find a few modifications to your code. Your question is pretty vague so I can't tell exactly where you're wishing to improve your code, but my suggestion uses recursion instead of the while loop (don't worry about stack overflows, F# can handle recursion very well and the whole recursive bit will be optimized into a loop at compile time), makes use of the use keyword (like C#'s using) and will swallow any exception happening in the process of the communication with the client. If an exception occurs, the server will not listen for other connections.
open System.IO
open System.IO.Pipes
let main() =
printfn "[F#] NamedPipeServerStream thread created."
let pipeServer = new NamedPipeServerStream("testpipe", PipeDirection.InOut, 4)
let rec loop() =
//wait for connection
printfn "[F#] Wait for a client to connect"
pipeServer.WaitForConnection()
printfn "[F#] Client connected."
try
// Stream for the request.
use sr = new StreamReader(pipeServer)
// Stream for the response.
use sw = new StreamWriter(pipeServer, AutoFlush = true)
// Read request from the stream.
let echo = sr.ReadLine();
printfn "[F#] Request message: %s" echo
// Write response to the stream.
echo |> sprintf "[F#]: %s" |> sw.WriteLine
pipeServer.Disconnect()
if [A CONDITION WHICH TELLS YOU THAT YOU WANT ANOTHER CONNECTION FROM THE CLIENT] then loop()
with
| _ as e -> printfn "[F#]ERROR: %s" e.Message
loop()
printfn "[F#] Client Closing."
pipeServer.Close()
Also please notice how the AutoFlush is set within the call to the constructor and how the pipeline operator is used to write the echo to the pipe, resulting in what looks (in my opinion) like cleaner code.