F# Script Ends Immediately After Execution (FSI) - winforms

When I double-click .fsx files the script ends immediately after execution. There is no chance of interacting with the script or see what it does.
I can barely see one of the scripts create a WinForms window, but it quickly closes.
I have tried several default Run actions (including sending to a .cmd file):
"C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsi.exe" "%1" %*
"C:\Program Files (x86)\Microsoft SDKs\F#\4.1\Framework\v4.0\fsi.exe" --quiet --exec "%1"

Both command lines you tried do indeed run the script and then exit. If you want to keep the REPL open to interact with the script, you need either --load:file.fsx or --use:file.fsx.
--use:file.fsx does roughly the same as just running fsi and then pasting the contents of file.fsx into the REPL. So for example if the file just contains let x = 2 then you can immediately type x;; and it will be recognized. This is the one you want if your file contains a bunch of values, statements, types and/or modules.
--load:file.fsx does roughly the same as just running fsi and typing #load "file.fsx". This means that values defined in this file will be in a separate namespace. This is the one you want if your file starts with a namespace or module declaration.

Related

How to transfer post-build event command line to batch file in MsBuild?

In my demo project's build event, (a class library project), to copy the build result .dll to a specific folder, (auto-created if it doesn't exist), I added following command line in Post-build event command line section:
xcopy /Y "$(TargetDir)$(TargetFileName)" "$(SolutionDir)DemoApp\bin\$(ConfigurationName)\Packages\"
It works perfectly.
Then I tried to replace that command line with a call to a new batch file called CopyPackage.bat located in $(SolutionDir). The content of the batch file is exactly the command line above:
call $(SolutionDir)CopyPackage.bat
Then I rebuild the project and get following error:
Severity Code Description Project File Line Suppression State
Error The command "call C:\TestProjects\DemoApp\CopyPackage.bat" exited with code 4. DemoApp
Do I miss something?
The solution after getting some hints from you all:
In post-build event command line I put: (see the params)
$(SolutionDir)CopyPackage.bat "$(TargetDir)$(TargetFileName)" "$(SolutionDir)DemoApp\bin\$(ConfigurationName)\Packages\"
In batch file CopyPackage.bat :
set targetfile=%~1
set targetdir=%~2
echo %targetfile%
echo %targetdir%
xcopy /Y %targetfile% %targetdir%
No need to use call you can simply invoke the batch script directly.
I do have to caution you, since the post-build targets have no way of knowing the inputs and outputs of the task, it will always have to execute the script, even if nothing has changed.
Instead, if you convert this to a msbuild target and you implement the input/output signalling correctly, you'll gain a lot of time by being able to leverage the incremental build features of MsBuild.
For example:
<Target Name="CopyOutputs"
Inputs="#(BuiltAssemblies)"
Outputs="#(BuiltAssemblies -> '$(OutputPath)%(Filename)%(Extension)')">
<Copy
SourceFiles="#(BuiltAssemblies)"
DestinationFolder="$(OutputPath)"/>
</Target>
More information on incremental builds and input/output signalling can be found:
MsBuild: transforms
MsBuild How-To: build incrementally
Extend the build process
call is an internal command of cmd.exe you should use
cmd.exe /c "$(SolutionDir)CopyPackage.bat"
instead.
Edit:
The content of the batch file is exactly the command line above
VS variables will not be properly resolved inside of the .bat file. You should pass them as parameters to batch file.
Changing the path in your CopyPackage.bat to absolute path can help resolve this.
Properties like these: $(TargetDir),$(SolutionDir) are recognized by msbuild.exe tool since they are part of msbuild properties and are defined or imported into current environment.
When using xcopy /Y "$(TargetDir)$(TargetFileName)" "$(SolutionDir)DemoApp\bin\$(ConfigurationName)\Packages\" in post-build-event,the msbuild tool can recognize them.So for the first time, it succeeds.
However, for the second time. The msbuild engine can recognize properties in post-build-event, so it calls the .bat successfully. But since the .bat can't recognize the Msbuild property(These properties can only be recognized by MSbuild.exe, not .bat or cmd.exe), the build will fail for not finding the path.

Why does my IrfanView command not work on batch file but work when typing directly in CMD?

I'm a first-day user of IrfanView and have a question. I have a bunch of multi-page tiff files and I want to split all of them individually. So I write a batch file with the command like this:
C:\Program Files\IrfanView>i_view64.exe D:\originaldirectory\filename1.tif /extract=(D:\newdirectory,tif)
C:\Program Files\IrfanView>i_view64.exe D:\originaldirectory\filename2.tif /extract=(D:\newdirectory,tif)
...and so on...
I put the batch file on D drive, let's say in folder "batchfolder". But it can't do the job, this message shows up for each unsuccessful case (all of them were unsuccessful):
D:\batchfolder>C:\Program Files\IrfanView D:\originaldirectory\filename1.tif /extract=(D:\newdirectory,tif) 1>i_view64.exe
'C:\Program' is not recognized as an internal or external command, operable program or batch file.
I guess that has something to do with the batch file location, so I bring it to C drive. But still it can't run properly, this time a different message shows up:
C:\>C:\Program Files\IrfanView D:\originaldirectory\filename1.tif /extract=(D:\newdirectory,tif) 1>i_view64.exe
Access is denied.
This C:\>C:\ makes me think maybe the C:\ part on the batch file was redundant. So I take it out to make it look like this:
Program Files\IrfanView>i_view64.exe D:\originaldirectory\filename1.tif /extract=(D:\newdirectory,tif)
...
But it doesn't work, either with the batch file on D or C drive.
I then try to type it directly in the CMD window and it works normally, like this:
C:\Program Files\IrfanView>i_view64.exe D:\originaldirectory\filename1.tif /extract=(D:\newdirectory,tif)
Can you tell where my batch file goes wrong?
This is another question. Typing (or copy and paste) the batch file contents into the CMD works OK. But upon successful splitting, the original, multi-image file automatically opens. How can I deactivate this feature?
Note: Cross-post here: https://irfanview-forum.de/showthread.php?t=11150&p=47111#post47111. Hope it doesn't violate policy.
enclose paths/filenames with spaces into quotes to tell the interpreter, it's not two words, but one string (or even better: get used to always enclose path/filenames):
"C:\Program Files\IrfanView\i_view64.exe" "D:\originaldirectory\filename1.tif" /extract=("D:\newdirectory",tif)`
Before you build a batchfile with dozends or hundreds of nearly identical lines, use a for loop to process all .tif files in the folder:
#echo off
for %%a in ("D:\originaldirectory\*.tif") do (
"C:\Program Files\IrfanView\i_view64.exe" "%%~fa" /extract=("D:\newdirectory",tif)
)
see for /? for more information.
You need to call the executable with quotes in the batch. Also, the > in the path will not work either. Also consider using a for loop instead of creating single batch lines.
Please try this:
"C:\Program Files\IrfanView\i_view64.exe" "D:\originaldirectory\filename1.tif" /extract=("D:\newdirectory",tif)

Batch Files - Closing Opened Text Files

I currently have a Windows batch file that runs an .exe file that uses a text file. I am trying to have the Windows batch file run the .exe file multiple times. This, however, requires the use of the same text files to read from. The command prompt gives me the error that the ".txt could not be opened" (I assume from this that it is already open.)
I am trying to see if there is a way in a .bat file to system call to kill that specific text file. The suggestions I see online are to use 'taskkill notepad.exe', but that returns "invalid argument" because the program doesn't open Notepad to use the text file.
Any suggestions would be appreciated.
It sounds like your existing script fails because the first instance of the exe is still open when the second instance starts.
One thing worth trying (and this depends on the nature of the application you are invoking) is to start the executable using the START /WAIT /B ... command. This makes the command interpreter wait for the program to exit before it moves onto the next command, so as long as nothing else is locking the text files you should be OK to move onto the next command.

Run batch file in the background

I have a batch file, this batch file will not start automatically, it will only run when i double click on it.
Can I run the batch file in the background when I double click on it.
Well, you can start it minimized with start, if that is enough. Really hiding it is difficult (although I can think of an option right now).
Basically you need to determine whether the batch has been started by double-clicking it. You can do this by defining a special variable and look for it:
#echo off
if not defined FOO (
set FOO=1
start /min "" %~0
exit /b
)
rem here whatever you wanted to do originally in the batch
As long as the FOO variable isn't defined (which is probably the default almost everywhere), this batch will launch itself minimized again, but with the variable defined first. Environments are passed to subprocesses, which is why this works.
you would generally need something else to run the script in that manor
i.e.
Create a shortcut, and set the “Run” field for the shortcut to “Minimized’.
Once you click or tab away from the cmd.exe window that the batch file is running it, it's "in the background" -- I'm not really sure what you want but it sounds like you might be asking how to run the batch file without displaying the cmd.exe window.
If so I can think of two ways: first, you can create a shortcut to the batch file, right click it, and in the properties there set the shortcut to run minimized (should be a drop down option next to Run).
You can also wrap invocation of the batch file in a VBScript file using Windows Script Host's shell object (calling the Run method) to run the batch file invisibly. Passing 0 as the intWindowStyle parameter will suppress display of a window or anything.
#Ghyath Serhal
I have used cmdow to do this on another program, it is an external application that can be used to modify the command prompt. To use it, you will need to either enter this code (see below) into it's own batch file, or into the command prompt, where it will run 'BatchFile.bat' with a hidden terminal window. I haven't found a way to use this in a single batch file, but I only found out about this today.
cmdow /run /hid 'BatchFile.bat'
Hope this helps.

Windows batch file for iterative invocation of other batch files

Consider a directory structure containing the following files:
\1.3\Baseline\GeneratedScripts\One\FullInstall.cmd
\1.3\Baseline\GeneratedScripts\Two\FullInstall.cmd
\1.3\Baseline\GeneratedScripts\Three\FullInstall.cmd
\1.3\Patches\Patch1\GeneratedScripts\One\FullInstall.cmd
\1.3\Patches\Patch1\GeneratedScripts\Two\FullInstall.cmd
\1.3\Patches\Patch1\GeneratedScripts\Three\FullInstall.cmd
\1.3\Patches\Patch2\GeneratedScripts\One\FullInstall.cmd
\1.3\Patches\Patch2\GeneratedScripts\Two\FullInstall.cmd
\1.3\Patches\Patch2\GeneratedScripts\Three\FullInstall.cmd
\1.3\Patches\Patch3\GeneratedScripts\One\FullInstall.cmd
\1.3\Patches\Patch3\GeneratedScripts\Two\FullInstall.cmd
\1.3\Patches\Patch3\GeneratedScripts\Three\FullInstall.cmd
I would like to construct a Windows batch file InstallEnvironment.cmd which:
Takes an environment name as a parameter; then
Executes the baseline install script, and each of the patch scripts in turn.
The batch file should automatically execute any additional patches that are added later.
Essentially I need to do something along the lines of this:
for %%_ in (1.3\**\GeneratedScripts\%%1\FullInstall.cmd) do cal %%_
However I'm not sure the wildcard system is rich enough to allow this as I don't get any matches for the ** directory wildcard.
For example, calling with the parameter "Two" should execute the following scripts, in order:
\1.3\Baseline\GeneratedScripts\Two\FullInstall.cmd
\1.3\Patches\Patch1\GeneratedScripts\Two\FullInstall.cmd
\1.3\Patches\Patch2\GeneratedScripts\Two\FullInstall.cmd
\1.3\Patches\Patch3\GeneratedScripts\Two\FullInstall.cmd
This will execute all the *.cmd files in the sub folders based on the argument:
for /r 1.3\ %%X in (GeneratedScripts\%1\*.cmd) do call "%%X"
In my experience, the %1 substitution works within directory names.
This should work:
InstallEnvironment.bat:
\1.3\Baseline\GeneratedScripts\%1\FullInstall.cmd
\1.3\Patches\Patch1\GeneratedScripts\%1\FullInstall.cmd
\1.3\Patches\Patch2\GeneratedScripts\%1\FullInstall.cmd
\1.3\Patches\Patch3\GeneratedScripts\%1\FullInstall.cmd
Edit this batch file to add additional patches in order, and it works. If you need to run the same batch file on multiple directories, create another batch file:
call InstallEnvironment.bat %1
call InstallEnvironment.bat %2
If you want to run a batch file in the background, use a vbs file to run that bat file in background instead.
Here is the code:
CreateObject("Wscript.Shell").Run"""" & Wscript.Arguments(0)& """",0,False
Save this exactly as invisible.vbs (or anything) and then make another batch file which will call your batch file to run it in background.
The code for the second batch file is:
wscript.exe "invisible.vbs" "Your_Batch_File.bat"
Then run the second batch file.
Note: WSH should be enabled on your computer, and the invisible.vbs file and the second batch file should be in the same folder. If not then you can give the full path to the invisible.vbs file in the 2nd batch file's script.

Resources