Java emulating the "open with" on a .bat file - java

I'm trying to automate an arduous process but I've run into a wall that I can't seem to google my way around.
This is the process that I'm trying to automate
The batch file contains:
cd %~dp0
"%~dp0raindrop.exe" -g om -i %1 -o "%~dp1
PAUSE
What I'm trying to do: Stream in from a folder a bunch of '.sm' files and pass them one by one through the bat file creating a Folder for the outputted file created from the .bat process.
Explaining what these set of commands do would be great as I would prefer to create one more fit for my purpose. Which is bulk converting and sorting, so the output directory assuming thats handled in that batch file would need to be understood.
What i've tried at the moment its just running the .bat as is

%1 is window-batch-ese for 'the first parameter'. That makes some sense, I hope.
%0 is window-batch-ese for 'the batch file itself'. If you think about it now knowing what %1 means, this does make a little bit of sense: It's the '0th parameter' - the one to the left of the first parameter, which is the batch file itself.
%~letters0 is a way to tell windows; I want %0, but, I want you to modify it. There are many letters. d in particular means 'drive letter', and p means path.
Thus,
%~dp0 is windows-batch-ese for 'the full path (including drive letter) to the directory where the batch file currently executing lives.
%~dp1 is windows-batch-ese for 'take param 1 and turn it into an absolute path, then give me the directory that contains this argument.
Thus, you should now be able to recreate what this batch script does in pure java:
It runs the file raindrop.exe, by asking windows to run that by providing the full, absolute path to that executable, which is located in the same place the batch file is located.
It then passes 6 arguments to it:
-g
-om
-i
the first parameter
-o
if the first parameter resolves to a file, then that file, turned into an absolute path, and then the directory (i.e. if passing 'foo.txt', and that is in C:\example\whatever\foo.txt, the last arg is C:\example\whatever).
Use ProcessBuilder and you can recreate this feature fully.
NB: Your batch script is probably broken; it's missing a closing quote. Also, the fact that %1 is not quoted means that any files with spaces in it will also break this batch script. I assume you have no need to replicate these bugs in the java take on this.
NB: Run raindrop.exe with ProcessBuilder. Forget the bat file, you don't want to run that.

Related

How to recursively call a Java program with PowerShell and pass in a file path

I am trying to batch rename files in a folder. For example, right now I want to remove the character at the second index in the names of all of the files in a given folder. I have written a Java program that will do this given the path of the file.
The problem is that I am trying to batch the process with PowerShell, and I have very little knowledge of PowerShell. I basically just started using it today, and mainly to test run my Java program from the command line. I decided to try PowerShell for this because I saw a YouTube video where someone used PowerShell recursively to remove a certain character (like a "-") from every spot it appears in every file name in a folder. I thought maybe I could recurse with PowerShell to batch the process of changing every file name.
I want to recursively call the Java program with PowerShell and have PowerShell pass in each path of each file one by one in a folder to the Java program. I don't know if this is possible, but I'm hoping it is.
I have tried the following, though since I don't really any knowledge of PowerShell, I don't really know what to try. "Copy" is the name of the folder in which the files I want to modify are located.
get-childitem -recurse | java -cp "C:\Users\Media PC\Documents\Renamer\src\main\java" org.example.Main $_.name
I am getting the Java program to run, because I'm getting an error back from the program saying I didn't pass in a proper file path.
Building on Abraham Zinala's helpful comment:
Leaving aside the fact that invoking an external program (i.e., creation of a child process) file by file is inefficient:
Get-ChildItem -File -Recurse | ForEach-Object {
java -cp "C:\Users\Media PC\Documents\Renamer\src\main\java" org.example.Main $_.FullName
}
Note: The -File switch limits results to just files (doesn't include directories).
PowerShell's automatic $_ variable can only be used inside script blocks ({ ... }), so using $_.name as an argument as-is won't work.
See this answer for all contexts in which $_ is meaningfully defined.
In order to pass an argument to a command that isn't designed to take its input directly from the pipeline, use the ForEach-Object cmdlet for custom-processing of each input object one at a time.
Inside the script block passed to it, you can use $_ to refer to the pipeline input object at hand.
Get-ChildItem outputs instances of the following .NET types:
System.IO.DirectoryInfo(for directories) and
System.IO.FileInfo (for files)
Their .FullName property contains their full, file-system-native path, so $_.FullName is a robust way to refer to just that. Given that .Name only reports the mere file name, it wouldn't be sufficient to identify the file at hand in a recursive traversal of the current dir.
In PowerShell (Core) 7+, you could use just $_, because there such instances consistently stringify as the value of their .FullName property (when passing arguments to an external program, objects are implicitly stringified) - unfortunately, this is not the case in Windows PowerShell; see this answer.

Why the BAT file launched from JMeter OS Sampler is not triggering the Maven execution?

Summary:- I need lots of dynamic data for my performance testing and it's not possible to generate those test data from Jmeter itself. Hence, I wrote a Java code which will generate these dynamic test data and will put those data into the excel file. This excel file can be consumed by JMeter script for the performance testing. Every iteration in JMeter needs a new set of test data and that's why I have created a bat file which will trigger the Maven execution(it's just mvn clean test) and will generate the fresh set of test data before each of iteration. Everything is working fine till this point. I just need to run the bat file from JMeter to trigger the test data creation before each iteration and that's the problem which I am facing
Problem:- As mentioned in the link How to run batch file(.bat) from Jmeter and as suggested by user #Dmitry T, I have added the OS sampler with the given parameters(See the screenshot below) but it is not starting the Maven execution. It is hitting the bat file(I put some msg command to check) but somehow it is not starting the execution. I tried the other solution given by the same user about using the Beanshell Sampler and running the command
Runtime.getRuntime().exec("C:/Windows/System32/cmd.exe /c D:/XXXX/XXX/XXXX/GenerateTestData.bat");
This is also not working. Am I missing something here? Please let me know if there is any solution for this? Appreciate any help on this?
The batch file is most likely not designed to work properly with current directory on execution being different to the directory containing the batch file. The current directory can be any directory. Very common are the directories %SystemRoot% (Windows directory) and %SystemRoot%\System32 or %SystemRoot%\SysWOW64 (Windows system directory) as current directory, whereby any directory can be the current directory on running a batch file.
A batch file referencing other files or directories relative to the batch file directory should set the current directory to the batch file directory or reference all directories and files with full batch file path.
The argument 0 of a batch file is always the batch file itself. The help output on running in command prompt window call /? explains how to reference an argument with a modifier. In this case %~dp0 should be used to get full path of the batch file.
So in the batch file can be used at top:
#echo off
cd /D "%~dp0"
The current directory is set with second command line to the directory containing the batch file as long as the batch file is stored on a drive with a drive letter.
There is another method to make the directory of the batch file the current directory which works even with batch file being stored on a network resource and the batch file is executed using its UNC path.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0" || exit /B
rem Other commands accessing files and directories in batch file directory
rem using no path or a path relative to current working directory.
popd
endlocal
The help output on running in a command prompt window pushd /? describes why this code works even with a UNC path on command extensions enabled which is made sure by the second command line which defines together with first command line completely the execution environment for the batch file without depending on configurations outside of the batch file.
Another solution is referencing all files and directories in batch file directory with full path which means with using %~dp0, for example "%~dp0ExcelFile.xlsx".
Note: The path string referenced with %~dp0 always ends with a backslash which is the directory separator on Windows as explained by Microsoft documentation about Naming Files, Paths, and Namespaces. Therefore concatenation of %~dp0 with another string like file/folder name or wildcard pattern should be done always without using an additional backslash for a 100% correct full file/folder/pattern argument string.
In the Command input provide full path to the cmd.exe
Change the Working directory to where your batch file lives
Use just batch file name in the Command Parameters
Something like:
See How to Run External Commands and Programs Locally and Remotely from JMeter article for more details.
Alternatively you can use Maven Exec Plugin to run your custom command before running the JMeter test

Translating a Jar-opening Batch file into its MacOS Equivalent

Hello again Stack Overflow!
I am currently working on a Java program that is essentially a digitized character sheet for a Dungeons and Dragons style adventure. I'm currently learning how to use IntelliJ IDEA, and while I haven't been able to figure out how to create a standalone executable .jar file, I have been able to find a workaround in the form of a .bat file that I have nicknamed rubberglove.bat (because if you can't open a jar, you use a...).
However, as in my previous post, I've run into a problem, as one of my new players uses a Mac, and since I don't know if it's possible to run rubberglove.bat in a non-Windows environment, I'll probably have to translate it into something MacOS can understand. However, I've never owned a Mac, so I'm not sure what the file extension even is, let alone what to put inside.
The contents of rubberglove.bat are shown below:
java -jar [program_name].jar
What would the Mac equivalent of this file and the commands inside? Thanks in advance for all your help!
Create a file called rubberglove (or rubberglove.sh, the file suffix is optional). And then set the execute bit. Something like
$ cat << EOF > rubberglove
#!/usr/bin/env bash
java -jar [program_name].jar
EOF
$ chmod +x rubberglove
$ ./rubberglove
Error: Unable to access jarfile [program_name].jar
Adjust "[program_name]" as needed.

How do I make my directory give the executable permissions to script files which are going to be created by my Java program?

I want my directory to give executable permissions (by default) to all the shell scripts which are going to be created in that directory after I run my Java program. I tried the following commands:
setfacl -d -m group:name:rwx /path/to/your/dir
find ./ -name "*.sh" -exec chmod +x {} \;
The first one is not showing any response while the second one works fine but I have to execute this command manually in terminal after my Java program has created all the scripts. This is not what i seek. I want this thing to be automatic. Here is what I am trying to achieve:
My Java program creates the .sh files in a directory.
Now the program would try to execute this script file.
Here is a Java code snippet which shows how it is going to execute the script files:
ExecuteShellComand obj = new ExecuteShellComand();
String command2 = "./script.sh";
String output2 = obj.executeCommand(command2);
It doesn't run unless I give the executable permissions to the script.sh. How do I do it? Is there any way around it? If I am not doing something in a way it should be done, feel free to give your suggestions. Thanks
Default ACL permissions are masked by the file's creation mode as specified in open and mkdir syscalls.
Since files are usually created with a default mode of 0666, execute permissions will be masked instead of inherited.
It's the responsibility of the program that creates the files to create them with the right permissions. If you set the permissions correctly when creating the scripts, you won't need ACL or chmod at all. The best way to fix this would be for your program to set the mode in the open call to 0777.
Java appears to have Files.createFile for this. Additionally, you have a more fuzzy File.setExecutable to do it after the fact, which is not Unix canonical behavior, but probably fine for your use case.

Runtime exec output path

I am trying to run a perl command with Java runtime exec in linux/ubuntu/gnome. The command generates an pdf file, but it saves it in my home folder. Is there any way that the exec method can set an output path for the commands executed? Thanks in advance.
The exec method just runs the command on the operating system, so you'll want to change the command you're running with exec more than anything in "Java" per se.
There are a few possibilities:
Change the working directory of your java program. The .pdf is being saved in your working directory because this is where the program is being run.
Unfortunately it's not simple to change this value after the program has been launched. It is, however, trivial to change before the program starts; just change the working directory before starting the program.
Move the file to it's desired location after it's been created in your home directory.
Change the command so that it includes the target location. Your perl script may have an option that will enable you to save it's output to a certain location (usually -o or --output). Using this your program would change from:
Runtime.exec("perl someprogram");
to something like:
Runtime.exec("perl someprogram -o /path/to/some.file")
You might be able to use "output redirection", if there is no option to do this.
Try something like what's below as your argument:
Runtime.exec("perl someprogram > /path/to/some.file")
Unfortunately, without knowing more details of your situation I can't provide more concrete advice.
While each approach has benefits and drawbacks, it's probably best to just implement the one that you understand best; if you can't get one to work, try another.
A good, free online resource for learning is Introduction to Linux: A Hands On Guide.
Section 2.2 has details on cd which you can use for 1..
Section 3.3, section 3 teaches about the mv command, which will be useful in 2..
Section 5.1 is about I/O redirection. Knowing about "output redirection" and the > operator, are important for 4..
For 3., you'll have to consult the documentation of the perl program you're using.
You could modify the Perl script to accept an absolute path for the output.
You can trying setting the working directory using exec(java.lang.String[], java.lang.String[], java.io.File) where File is the directory the command is executed from.
If all else fails, you'll can always copy the generated file from the Home directory to your final location.

Categories

Resources