Unix executable changes to TextEdit document when copied - java

I have the following script, of which you can see below. The function of this Java script is to copy a Mac app, of which is placed in the same folder as the java program. It first finds the path of the folder, which the app and java program is in. It then copies all the content to the documents folder on the Mac device. When that is done it is then supposed to run that app of which it has copied to the documents folder.
The only issue is that it isn't able to do so. The reason being that whenever it copies the app, the JavaAppLauncher which is found within the content of the mac app has changed from a unix executable to a regular TextEdit document and thus can't actually launch the app. However if I were to copy the app manually by copying it myself and not using the java program, there is no issue. I am not sure whether this issue is caused by my code, or whether it is just a general thing?
Important note, the .app does work when I just run the regular non copied version, but as soon as it is the copied version, which as been copied through Java it doesn't work because the change of the Unix executable.
public class LaunchProg {
static String usernameMac2 = System.getProperty("user.name");
static File propFile = new File (".");
static String pathString = propFile.getAbsolutePath();
static int pathhLeng = pathString.length();
static int pathReaLeng = pathhLeng -1;
static String filNamMac = "AppNam.app";
static String pFPathRelMac = pathString.substring(0,pathReaLeng);
private static final File fSourceMac = new File(pFPathRelMac);
private static final File AppFold = new File ("/Users/" + usernameMac2 + "/Documents");
static File fileCret = new File("fCret.txt");
public static void main(String[] args) throws IOException {
System.out.println(pFPathRelMac);
launchMac();
}
static void launchMac() throws IOException {
if (!fileCret.exists()){
try {
FileUtils.copyDirectory(fSourceMac, AppFold);
PrintWriter pFW = new PrintWriter(fileCret);
pFW.println("Created File For Check");
pFW.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
String command = "open /Users/" + usernameMac2 + "/Documents/AppNam.app";
Process staAp2 = Runtime.getRuntime().exec(command);
}
}
}
}

Related

Runtime exec command working when when run from terminal but not eclipse

I'm trying to use tesseract to do OCR on an image in java. I realize there are wrappers like Tess4J that provide a bunch more functionality and stuff, but I've been struggling to get it set up properly. Simply running a one-line command with Runtime is really all I need anyways since this is just a personal little project and doesn't need to work on other computers or anything.
I have this code:
import java.io.IOException;
public class Test {
public static void main(String[] args) {
System.out.println(scan("full-path-to-test-image"));
}
public static String scan(String imgPath) {
String contents = "";
String cmd = "[full-path-to-tesseract-binary] " + imgPath + " stdout";
try { contents = execCmd(cmd); }
catch (IOException e) { e.printStackTrace(); }
return contents;
}
public static String execCmd(String cmd) throws java.io.IOException {
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
When it's compiled and run directly from terminal, it works perfectly. When I open the exact same file in eclipse, however, it gives an IOException:
java.io.IOException: Cannot run program "tesseract": error=2, No such file or directory
What's going on? Thank you for any help.
Check the working folder in the run configuration for the Test class in Eclipse. I bet it's different from the one when you run the same program from a terminal.

Finding batch file using parameter in java

I have a batch file (test.bat) which has the command copy NUL test.txt. I have a java program, when i run it and when i enter a URL in the web browser e.g http://localhost:8080/runbatchfileparam, i get a result as either {"result":true} or {"result":false}. True means the java application has executed the batch file correctly (test.txt is created under the directory).
What i want to do now is, i want the java program to be able to take in parameters. E.g. User should be able to enter http://localhost:8080/runbatchfileparam/testabc.bat as the URL in web browser and the result should be {"result":true} if testabc.bat file is found and is executed (under desktop) and {"result":false} if the testabc.bat file is not found and not executed . (Note: All batch files are created under desktop filepath: C:/Users/attsuap1/Desktop)
I have edited my controller to take in a parameter and done the #PathVariable. In my codes, the fileName variable refers to the batch file name that i have created (test.bat, test123.bat) Command in test.bat: copy NUL test.txt Command in test123.bat: copy NUL test123.txt. However, i keep getting the result as {"result": false}. Which means the java program is not able to find the batch file and execute it.
Here are my codes:
RunBatchFile.java
public ResultFormat runBatch(String fileName) {
String var = fileName;
String filePath = "C:/Users/attsuap1/Desktop" + var;
try {
Process p = Runtime.getRuntime().exec(filePath);
int exitVal = p.waitFor();
return new ResultFormat(exitVal == 0);
} catch (Exception e) {
e.printStackTrace();
return new ResultFormat(false);
}
}
ResultFormat.java
private boolean result;
public ResultFormat(boolean result) {
this.result = result;
}
public boolean getResult() {
return result;
}
BatchFileController
private static final String template = "Sum, %s!";
#RequestMapping("/runbatchfileparam/{param}")
public ResultFormat runbatchFile(#PathVariable("param") String fileName ) {
RunBatchFile rbf = new RunBatchFile();
return rbf.runBatch(fileName);
}
Application.java
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
What do i have to edit or what should i add to the codes to achieve what i want?
After this line:
String filePath = "C:/Users/attsuap1/Desktop" + var;
Try to print the contents of filePath, i suspect that you come up with something like this:
C:/Users/attsuap1/Desktoptestabc.bat

AccessDeniedException: C:\Windows\System32\drivers\etc\hosts

I'm trying to make a java program which blocks the facebook page in web browsers. I'm trying to overwrite somehow the hosts file, but the file is disabled to overwriting. I tried to copy him to my desktop, then append a line which blocks the page, and then copy to the etc folder and click to copy (or overwrite) the file. But i can't do it in java, all what i did was create another file in the same folder and append lines to it. But then i can't copy the new file to old, i dont know how to do it, here's my code, i'm waiting for a solutions :)
public class Sandbox {
private final static File zdroj = new File("C:\\Windows\\System32\\drivers\\etc\\hosts");
private final static File ciel = new File("C:\\Windows\\System32\\drivers\\etc\\hostsTemp");
public static void main(String[] args) {
try {
Files.copy(zdroj.toPath(), ciel.toPath());
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(ciel, true)));
writer.append("\n\n127.0.0.1 facebook.com www.facebook.com http://www.facebook.com/ http://facebook.com");
writer.close();
Files.delete(zdroj.toPath());
Files.copy(ciel.toPath(), zdroj.toPath());
} catch (IOException ex) {
Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
You will need to run your application with elevated permissions. Try starting it with some administrator user.

Create a public folder in internal storage

Sorry for my English, but I want to write in this file because in my opinion is the best.
Now my problem:
I want to create a folder in Internal storage to share with 2 application.
In my app, I downloaded an Apk from my server and I run it.
Before I used external storage and everything worked.
Now I want to use the internal storage for users that don't have an external storage.
I use this:
String folderPath = getFilesDir() + "Dir"
but when i try to run the Apk, it doesn't work, and I can't find this folder on my phone.
Thank you..
From this post :
Correct way:
Create a File for your desired directory (e.g., File path=new
File(getFilesDir(),"myfolder");)
Call mkdirs() on that File to create the directory if it does not exist
Create a File for the output file (e.g., File mypath=new File(path,"myfile.txt");)
Use standard Java I/O to write to that File (e.g., using new BufferedWriter(new FileWriter(mypath)))
Enjoy.
Also to create public file I use :
/**
* Context.MODE_PRIVATE will create the file (or replace a file of the same name) and make it private to your application.
* Other modes available are: MODE_APPEND, MODE_WORLD_READABLE, and MODE_WORLD_WRITEABLE.
*/
public static void createInternalFile(Context theContext, String theFileName, byte[] theData, int theMode)
{
FileOutputStream fos = null;
try {
fos = theContext.openFileOutput(theFileName, theMode);
fos.write(theData);
fos.close();
} catch (FileNotFoundException e) {
Log.e(TAG, "[createInternalFile]" + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "[createInternalFile]" + e.getMessage());
}
}
Just set theMode to MODE_WORLD_WRITEABLE or MODE_WORLD_READABLE (note they are deprecated from api lvl 17).
You can also use theContext.getDir(); but note what doc says :
Retrieve, creating if needed, a new directory in which the application can place its own custom data files. You can use the returned File object to create and access files in this directory. Note that files created through a File object will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.
Best wishes.
You can create a public into a existing system public folder, there is some public folder accessible from internal storage :
public static String DIRECTORY_MUSIC = "Music";
public static String DIRECTORY_PODCASTS = "Podcasts";
public static String DIRECTORY_RINGTONES = "Ringtones";
public static String DIRECTORY_ALARMS = "Alarms";
public static String DIRECTORY_NOTIFICATIONS = "Notifications";
public static String DIRECTORY_PICTURES = "Pictures";
public static String DIRECTORY_MOVIES = "Movies";
public static String DIRECTORY_DOWNLOADS = "Download";
public static String DIRECTORY_DCIM = "DCIM";
public static String DIRECTORY_DOCUMENTS = "Documents";
To create your folder, use this code :
File myDirectory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS), "MyPublicFolder");
myDirectory.mkdir();
With this example, a public will be created in Documents and can be visible in any file's explorer app for Android.
try the below
File mydir = context.getDir("Newfolder", Context.MODE_PRIVATE); //Creating an internal dir;
if(!mydir.exists)
{
mydir.mkdirs();
}
This is what i have used and is working fine for me:
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File file = new File(extStorageDirectory, fileName);
File parent=file.getParentFile();
if(!parent.exists()){
parent.mkdirs();
}
This will create a new directory if not already present or use the existing if already present.

Self-destructing application

Along the lines of "This tape will self-destruct in five seconds. Good luck, Jim"...
Would it be possible for an application to delete itself (or it's executable wrapper form) once a preset time of use or other condition has been reached?
Alternatively, what other approaches could be used to make the application useless?
The aim here is to have a beta expire, inviting users to get a more up-to-date version.
It is possible. To get around the lock on the JAR file, your application may need to spawn a background process that waits until the JVM has exited before deleting stuff.
However, this isn't bomb-proof. Someone could install the application and then make the installed files and directories read-only so that your application can't delete itself. The user (or their administrator) via the OS'es access control system has the final say on what files are created and deleted.
If you control where testers download your application, you could use an automated build system (e.g. Jenkins) that you could create a new beta versions every night that has a hard-coded expiry date:
private static final Date EXPIRY_DATE = <90 days in the future from build date>;
the above date is automatically inserted by the build process
if (EXPIRY_DATE.before(new Date()) {
System.out.println("Get a new beta version, please");
System.exit(1);
}
Mix that with signed and sealed jars, to put obstacles in the way of decompiling the bytecode and providing an alternative implementation that doesn't include that code, you can hand out a time-expiring beta of the code.
The automated build system could be configured to automatically upload the beta version to the server hosting the download version.
Since Windows locks the JAR file while it is running, you cannot delete it from your own Java code hence you need a Batch file:
private static void selfDestructWindowsJARFile() throws Exception
{
String resourceName = "self-destruct.bat";
File scriptFile = File.createTempFile(FilenameUtils.getBaseName(resourceName), "." + FilenameUtils.getExtension(resourceName));
try (FileWriter fileWriter = new FileWriter(scriptFile);
PrintWriter printWriter = new PrintWriter(fileWriter))
{
printWriter.println("taskkill /F /IM \"java.exe\"");
printWriter.println("DEL /F \"" + ProgramDirectoryUtilities.getCurrentJARFilePath() + "\"");
printWriter.println("start /b \"\" cmd /c del \"%~f0\"&exit /b");
}
Desktop.getDesktop().open(scriptFile);
}
public static void selfDestructJARFile() throws Exception
{
if (SystemUtils.IS_OS_WINDOWS)
{
selfDestructWindowsJARFile();
} else
{
// Unix does not lock the JAR file so we can just delete it
File directoryFilePath = ProgramDirectoryUtilities.getCurrentJARFilePath();
Files.delete(directoryFilePath.toPath());
}
System.exit(0);
}
ProgramDirectoryUtilities class:
public class ProgramDirectoryUtilities
{
private static String getJarName()
{
return new File(ProgramDirectoryUtilities.class.getProtectionDomain()
.getCodeSource()
.getLocation()
.getPath())
.getName();
}
public static boolean isRunningFromJAR()
{
String jarName = getJarName();
return jarName.contains(".jar");
}
public static String getProgramDirectory()
{
if (isRunningFromJAR())
{
return getCurrentJARDirectory();
} else
{
return getCurrentProjectDirectory();
}
}
private static String getCurrentProjectDirectory()
{
return new File("").getAbsolutePath();
}
public static String getCurrentJARDirectory()
{
try
{
return getCurrentJARFilePath().getParent();
} catch (URISyntaxException exception)
{
exception.printStackTrace();
}
throw new IllegalStateException("Unexpected null JAR path");
}
public static File getCurrentJARFilePath() throws URISyntaxException
{
return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
}
}
Solution inspired by this question.
Here is a better method for Windows:
private static void selfDestructWindowsJARFile() throws Exception
{
String currentJARFilePath = ProgramDirectoryUtilities.getCurrentJARFilePath().toString();
Runtime runtime = Runtime.getRuntime();
runtime.exec("cmd /c ping localhost -n 2 > nul && del \"" + currentJARFilePath + "\"");
}
Here is the original answer.
it is pretty possible i guess. maybe you can delete the jar like this and make sure the application vanishes given that you have the rights.
File jar = new File(".\\app.jar");
jar.deleteOnExit();
System.exit(0);
also using something like Nullsoft Scriptable Install System which enables you to write your own installed/uninstaller should help.

Categories