Calling batch file from F-Sharp - batch-file

Is there any way i can call a batch-file from within my F# program? My batch file is called eso.bat, and is to download the html content of a website. The file works, but it would be nice if it could be done automatically by the program itself.

The simple way is:
open System.Diagnostics
Process.Start "..\eso.bat"
if you need to pass parameteres or specify the starting directory then:
open System.Diagnostics
let procStart = ProcessStartInfo("eso.bat", "params", WorkingDirectory = "..")
let proc = new Process(StartInfo = procStart)
proc.Start()

Related

Open file in the default application WinForms (.NET Core) [duplicate]

i want to ask for help with opening a file from c# app with associated app.
I tried this:
ProcessStartInfo pi = new ProcessStartInfo(file);
pi.Arguments = Path.GetFileName(file);
pi.UseShellExecute = true;
pi.WorkingDirectory = Path.GetDirectoryName(file);
pi.FileName = file;
pi.Verb = "OPEN";
Process.Start(pi);
or this:
Process.Start(file);
where string file in both examples represents full path to the file trying to open. Now, everything is working well, except the (jpg) images with ACDSee app. Irfanview associations works well, MS office documents too. After trying to open the jpg image associated with acdsee it just runs the acdsee in the notification area and does not open the file.
I discovered, that in the registry CLASSES_ROOT for *.jpg images, there is an ACDSee.JPG value as associated app, and under this key there is in the shell->Open->Command a path:
"C:\Program Files\ACD Systems\ACDSee\ACDSee.exe" /dde
and I thing that this weird /dde is the reason, why i cannot open the file. I realized that in the same reg key shell->Open there is some DDEExec key entry with value [open("%1")]
For Irfan view or other checked app there is not a ddeexec, just the normal command like
"C:\Program Files (x86)\IrfanView\i_view32.exe" "%1"
that can be run from command line after swaping the %1 for file name, but I could not run the command from acdsee entry in the command line :(
So my question is, how can I set up the ProcessStartInfo object to ensure that it will run all the files as it would be in the explorer by doubleclick, the standards and this DDEExec ones? Is there something other like DDEExec that I shoul be aware of?
thanks and sorry for my EN
UPDATE: because this question still gets upvotes, I want to clarify that accepted answer works. I only had problem with old version of ACDSee and not with the Process.Start command or with the jpg extension.
Just write
System.Diagnostics.Process.Start(#"file path");
example
System.Diagnostics.Process.Start(#"C:\foo.jpg");
System.Diagnostics.Process.Start(#"C:\foo.doc");
System.Diagnostics.Process.Start(#"C:\foo.dxf");
...
And shell will run associated program reading it from the registry, like usual double click does.
In .Net Core (as of v2.2) it should be:
new Process
{
StartInfo = new ProcessStartInfo(#"file path")
{
UseShellExecute = true
}
}.Start();
Related github issue can be found here
This is an old thread but just in case anyone comes across it like I did.
pi.FileName needs to be set to the file name (and possibly full path to file ) of the executable you want to use to open your file. The below code works for me to open a video file with VLC.
var path = files[currentIndex].fileName;
var pi = new ProcessStartInfo(path)
{
Arguments = Path.GetFileName(path),
UseShellExecute = true,
WorkingDirectory = Path.GetDirectoryName(path),
FileName = "C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe",
Verb = "OPEN"
};
Process.Start(pi)
Tigran's answer works but will use windows' default application to open your file, so using ProcessStartInfo may be useful if you want to open the file with an application that is not the default.

When starting a process how do I set the directory for that process to read/write files?

In a WPF project this line is very simple to start mspaint with a given filename
Process.Start("mspaint.exe", filename)
While mspaint.exe will work with 'filename' in it's directory, if I try to open other files or do a 'SaveAs', mspaint.exe is looking at the Visual Studio \bin directory where the application was compiled to. Even if I move the .exe elsewhere, it keeps looking at the \bin location.
I tried the following:
Dim process1StartInfo As New ProcessStartInfo
process1StartInfo.WorkingDirectory = "C:\Users\theuser\Pictures"
process1StartInfo.FileName = "mspaint.exe"
process1StartInfo.Arguments = filename
process1StartInfo.UseShellExecute = False
Dim process1 = Process.Start(process1StartInfo)
I thought setting .WorkingDirectory would change the behavior but it does not.
Is it possible to and how do I change the directory that mspaint.exe is looking at when it is launched from within an application? Especially after the application is compiled and moved.

Where "io.open" saves the file if it doesn't exist yet?

I could find out here, how can I create a new file with pure Lua code. The next snippet should do it theoretically:
file = io.open("test.txt", "w")
file:write("Hello World")
file:close()
However, I can't find the created file in the folder of the source code file. Where does it save the file - if it even creates a new one?
If not, what's the way of doing it?
It will use the processes current working directory (CWD) which is going to wherever your shell/environment was when you ran the script.

What is a relative path like in C?

I am now using Visual C++ 2010 to open a txt file.
fp = fopen("E:\\CProg\\Huffman\\Debug\\Huffman.txt","r"); //Right
//Wrong
//fp = fopen(".\\Huffman.txt","r");
//fp = fopen("\\Huffman.txt","r");
//fp = fopen("Huffman.txt","r");
In VB.NET, I used to write like this: Application.Startpath & "\". Then how do I make it in C?
Relative to what? On "all relevant platforms", if you use a filename that's not absolute it will be resolved relative to the current directory.
The following is for Windows.
If you are writing a console application, the application will start with the current directory set to whatever the command prompt shows. Without further research I can't tell what the initial current directory for a GUI application will be.
If you want your filename to be relative to the Installation directory you'll have to use something like the Win32 function GetModuleFileNameW() and work your way from there (the function gives you the pathname to the exe file; remove the last component to get the directory, and append whatever path you want to append)-
There is no direct way to say "I want this filename to be used relative to the installation directory".

How do I call a batch file from an MSI

I have an msi installer that needs to call a few batch files to finish the install procedure. The batch file copies extra files from the installer to a few directories and then modifies permissions on several of those directories. We want to continue using the batch files because there is not a lot of time left in our development schedule. I am not using WIX.
If possible I would like to capture the output of the batch as it goes and write it to a log file.
Found bellow is the code I am using to try to run the batch file from a custom action. It opens a cmd window, runs for a while but never seems to finish. If I run the same batch files directly from the command prompt they work.
//Set the environment to the directory containing the bat files
ProcessStartInfo info = new ProcessStartInfo(batch);
info.WindowStyle = ProcessWindowStyle.Hidden;
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
if (!string.IsNullOrEmpty(argument))
info.Arguments = argument;
Process process = new Process();
process.StartInfo = info;
process.Start();
// Capture the standard error and standard output
What am I doing wrong?
I believe you'll need to create a custom action. See this question.
Many anti-virus programs may stop execution of .BAT files during an installation process, you should really be doing this using standard Windows Installer functionality or as a C++ Custom Action

Resources