This is not about creating a batch file or executing a batch file from java but creating a binary from them.
I am not very sure about Linux shell scripts but is know that for Windows Batch scripts there are some programs like Batch to Exe Converter. But i want to do it programmatically.
Suppose I read the contents of a batch file from a file :
public static String loadFile(String filepath) {
List<String> lines = Collections.emptyList();
try
{
lines =
Files.readAllLines(Paths.get(filepath), StandardCharsets.UTF_8);
}
catch (IOException e)
{
e.printStackTrace();
}
String s = "";
for(String line:lines){
s += line + "\n"
}
return s;
}
Now i want to convert it to an exe.
Purpose
My main purpose is to create small executables from those scripts for some small automations which will be used instead of the scripts themselves.
For example:-
I have a setup.bat file.
I have my program to automatically generate the batch every time I make any changes(add files) now i also want to have executables along with the scripts.
I also a curious whether a similar thing is possible for Linux shell scripts(creating executables).
Moreover i this is not possible through Java directly can we some how do it using JNI?
i have written a python script to goto a website and scrape some text off the website and save that text into a text file on my computer
from selenium import webdriver
import os
chrome_path = r"C:\tf_alert\chromedriver.exe"
driver = webdriver.Chrome(chrome_path)
driver.get("https://www.minuteinbox.com/")
email = driver.find_element_by_xpath("""/html/body/div[2]/div[3]/div[1]/div[3]/div/span""").text
strEmail = str(email)
mailMan = open("10MAIL.txt", "a")
mailMan.write(strEmail)
mailMan.close()
os.system("taskkill /im py.exe")
when i run the script from where it is located on my computer all works fine and text is properly written to text file on my computer
but when i try to integrate the python script into a java program (code below), the text scraped off of the website does not get written to text file
public void SimpleTest() throws InterruptedException, IOException {
Desktop desktop01 = Desktop.getDesktop();
File file01 = new File("C:\\tf_alert\\other python projects\\mailMan.py");
if (file01.exists()) {
desktop01.open(file01);
}
Thread.sleep(20000);
StringBuilder contentBuilder01 = new StringBuilder();
try (Stream<String> stream = Files.lines(Paths.get("C:\\tf_alert\\other python projects\\10MAIL.txt"), StandardCharsets.UTF_8)) {
stream.forEach(s -> contentBuilder01.append(s).append(""));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(contentBuilder01);
PrintWriter pw = new PrintWriter("C:\\tf_alert\\other python projects\\10MAIL.txt");
pw.close();
}
the purpose of the java program above is to activate the python script to scrape text off a website, then get the text written from the python script from the file on my computer, print the text to console, and then clear the text file so that all is ready for next execution
the problem is occuring during the writing of text mailMan.write(strEmail) in python code because when java prints the text from the text file it prints a blank ""
i suppose there is interference between java and python
can anyone help out?
You are not executing the python script.
Running a .py file from Java should help you.
Another source: Three ways to run Python programs from Java
to fix this problem i created a windows batch file that changes directory to where the python file is located and starts that file
cd C:\your-directory
start yourscript.py
I have java program that starts excel spreadsheet for them command line and wait for it to be closed to take next action as below. (btw my excel runs macro so I close the spreadsheet automatically when my macro finish executing to indicate it is done)
p = Runtime.getRuntime().exec("cmd /c start /wait C:\\"+excelSheet);
p.waitFor();
System.out.print("finished "+count + " "+ excelSheet);
However I want my java program to starts 2 excel spreadsheets and each time one sheet closes, I want to take action. The problem that excel 2010 starts both spreadsheets using one instance of Excel. Therefore my java program only detects when the instance of the Excel is closed which means both spreadsheets has to close.
How can I solve it ? Whether it is Java code, Excel code, some other innovative method? Please help
Thank you
PS: I am using apache poi to write to excel before starting and read from it after closing
You can periodically open the file for writing (just open a normal FileOutputStream on it in append mode - if this raises an IOException then the file is still open)
public boolean isStillOpenOnWindows(File file) {
try {
FileOutputStream out = new FileOutputStream(file, true);
out.close();
// Not open anymore
return false;
} catch (IOException e) {
// Still open
return true;
}
}
As the name of the method implies, this is not cross-platform, it only works on Windows because Windows doesn't allow to processes to have a file open for writing at the same time.
Since you're talking about Excel, it's likely that you mean Windows, but there is Office for Mac and this trick wouldn't work on Mac OS.
I open office files (docx, xlsx) by using Runtime.getRuntime().exec(String cmd) function. Simultaneously I store meta data of these files in a database. In order to keep integrity I lock the file with a flag in the meta data so that no other user concurrently can modify the file. This implies that the flag must be automatically resetted after the user closes the file (e.g. closes the external process).
Here's the snippet that opens the file:
File file = new File("c:/test.docx");
Process process = null;
if(file.getName().endsWith("docx")) {
process = Runtime.getRuntime().exec("c:/msoffice/WINWORD.EXE "+file.getAbsolutePath());
} else if(file.getName().endsWith("xlsx")) {
process = Runtime.getRuntime().exec("c:/msoffice/EXCEL.EXE "+file.getAbsolutePath());
}
if(process!=null) {
new ProcessExitListener(file, process);
}
Here's my listener that waits until the user closes the file (and finally unlocks the file by setting the flag in the meta data):
private class ProcessExitListener extends Thread {
private File file;
private Process process;
public ProcessExitListener(File file, Process process) throws IOException {
this.setName("File-Thread ["+process.toString()+"]");
this.file = file;
this.process = process;
this.start();
}
#Override
public void run() {
try {
process.waitFor();
database.unlock(file);
} catch (InterruptedException ex) {
// print exception
}
}
}
This works fine for different file types, e.g. if I open 1 docx and 1 xlsx file simultaneously. But when opening 2 docx files, one of the process exits right after it has been initialized.
Any ideas why ?
Thanks for your help in advance!
But when opening 2 docx files, one of the process exists right after it has been initialized.
Probably because winword.exe process finds out that there is already one instance of it running, so instead of keeping two instances in memory, it just asks the first instance to open the second document. Don't know how it looks from GUI perspective, but looking at the task manager, try opening two Word documents from Windows Explorer. The second file won't cause second winword.exe process to start.
I can reproduce the exact same behaviour on Ubuntu Linux. When I ran:
$ geany foo.txt
and the geany editor wasn't yet running, the console hangs until I close the editor. But if instead I open another terminal and call:
$ geany bar.txt
this returns immediately and bar.txt is simply opened as another tab in already existing process.
I have created a text file in Unix environment using Java code.
For writing the text file I am using java.io.FileWriter and BufferedWriter. And for newline after each row I am using bw.newLine() method (where bw is object of BufferedWriter).
And I'm sending that text file by attaching in mail from Unix environment itself (automated that using Unix commands).
My issue is, after I download the text file from mail in a Windows system, if I
opened that text file the data is not properly aligned. newline() character is
not working, I think so.
I want same text file alignment as it is in Unix environment, if I opened the
text file in Windows environment also.
How do I resolve the problem?
Java code below for your reference (running in Unix environment):
File f = new File(strFileGenLoc);
BufferedWriter bw = new BufferedWriter(new FileWriter(f, false));
rs = stmt.executeQuery("select * from jpdata");
while ( rs.next() ) {
bw.write(rs.getString(1)==null? "":rs.getString(1));
bw.newLine();
}
Java only knows about the platform it is currently running on, so it can only give you a platform-dependent output on that platform (using bw.newLine()) . The fact that you open it on a windows system means that you either have to convert the file before using it (using something you have written, or using a program like unix2dos), or you have to output the file with windows format carriage returns in it originally in your Java program. So if you know the file will always be opened on a windows machine, you will have to output
bw.write(rs.getString(1)==null? "":rs.getString(1));
bw.write("\r\n");
It's worth noting that you aren't going to be able to output a file that will look correct on both platforms if it is just plain text you are using, you may want to consider using html if it is an email, or xml if it is data. Alternatively, you may need some kind of client that reads the data and then formats it for the platform that the viewer is using.
The method newLine() ensures a platform-compatible new line is added (0Dh 0Ah for DOS, 0Dh for older Macs, 0Ah for Unix/Linux). Java has no way of knowing on which platform you are going to send the text. This conversion should be taken care of by the mail sending entities.
Don't know who looks at your file, but if you open it in wordpad instead of notepad, the linebreaks will show correct. In case you're using a special file extension, associate it with wordpad and you're done with it. Or use any other more advanced text editor.
bw.newLine(); cannot ensure compatibility with all systems.
If you are sure it is going to be opened in windows, you can format it to windows newline.
If you are already using native unix commands, try unix2dos and convert teh already generated file to windows format and then send the mail.
If you are not using unix commands and prefer to do it in java, use ``bw.write("\r\n")` and if it does not complicate your program, have a method that finds out the operating system and writes the appropriate newline.
If I understand you right, we talk about a text file attachment.
Thats unfortunate because if it was the email's message body, you could always use "\r\n", referring to http://www.faqs.org/rfcs/rfc822.html
But as it's an attachment, you must live with system differences. If I were in your shoes, I would choose one of those options:
a) only support windows clients by using "\r\n" as line end.
b) provide two attachment files, one with linux format and one with windows format.
c) I don't know if the attachment is to be read by people or machines, but if it is people I would consider attaching an HTML file instead of plain text. more portable and much prettier, too :)
Encapsulate your writer to provide char replacement, like this:
public class WindowsFileWriter extends Writer {
private Writer writer;
public WindowsFileWriter(File file) throws IOException {
try {
writer = new OutputStreamWriter(new FileOutputStream(file), "ISO-8859-15");
} catch (UnsupportedEncodingException e) {
writer = new FileWriter(logfile);
}
}
#Override
public void write(char[] cbuf, int off, int len) throws IOException {
writer.write(new String(cbuf, off, len).replace("\n", "\r\n"));
}
#Override
public void flush() throws IOException {
writer.flush();
}
#Override
public void close() throws IOException {
writer.close();
}
}