I'm developing a vehicle storage application. One feature is being able to store documents in different formats (word, excel, pdf) on a remote server WITHOUT having to map the server as separate drive.
Everything works fine if the file to be opened is on the local hard drive (ie, "C:/Documents/FileToOpen.docx"), but I can't figure out the path structure for a path (ie, "C:/Documents/FileToOpen.docx" on server "SERVER06"). I've tried "//SERVER06/C/Documents/FileToOpen.docx" and permutations thereof, but no joy so far.
public class Attachments extends javax.swing.JFrame {
String docPath = "C:/Program Files/Microsoft Office/Office14/WINWORD.EXE";
String excelPath = "C:/Program Files/Microsoft Office/Office14/EXCEL.EXE";
String pdfPath = "C:/Program Files/Adobe/Reader 11.0/Reader/AcroRd32.exe";
/**
* Creates new form Attachments
*/
public Attachments() {
initComponents();
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
this.setResizable(false);
}
public void setList(Set attachmentList) {
DefaultListModel model = new DefaultListModel();
Iterator i = attachmentList.iterator();
int counter = 0;
while (i.hasNext()) {
model.add(counter, (Attachment) i.next());
counter++;
}
listAttachments.setModel(model);
}
//form generation
private void btnViewActionPerformed(java.awt.event.ActionEvent evt) {
Attachment a = (Attachment) listAttachments.getSelectedValue();
String type = a.getAttachmentUrl().substring(a.getAttachmentUrl().indexOf("."));
String prog = "";
if (type.substring(0, 2).equals(".d")) {
prog = docPath;
} else if (type.substring(0, 2).equals(".p")) {
prog = pdfPath;
} else if (type.substring(0, 2).equals(".x")) {
prog = excelPath;
}
String commandString = "\"" + prog + "\" \"" + a.getAttachmentUrl() + "\"";
Runtime rt = Runtime.getRuntime();
try {
rt.exec(commandString);
} catch (IOException ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
private void jButtonCloseActionPerformed(java.awt.event.ActionEvent evt) {
this.setVisible(false);
this.dispose();
}
Is there a way to accomplish this?
Assuming your server is using Windows operating system, the server firstly need to share the folder that contains the documents. To do this, go to the server, select the folder, right click and choose 'share'. To verify, go back to the client machine, open windows explorer and type \SERVER06
If your folder sharing is successful, you should see a folder called 'Documents'. If all these are fine this far, your application just need to open the file using "\\SERVER06\Documents\FileToOpen.docx".
Related
I'm working on an application written in Java. The application is composed of many modules (maven). My task is to add a new module containing the application code written in ElectronJS and run it with Java code.
I did it this way.
private void turnOnElectronApp() {
ElectronAppRunner electronAppRunner = new ElectronAppRunner();
electronAppRunner.turnOnElectronApp();
}
public class ElectronAppRunner {
public void turnOnElectronApp() {
String user_dir = System.getProperty("user.dir");
user_dir += "/electron-app/src/main/electron-frontend-main";
System.out.println(user_dir);
String command = "npm start";
File workDir = new File(user_dir);
Runtime rt = Runtime.getRuntime();
try {
Process pr = rt.exec(command, null, workDir);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The application starts but the problem arises when building the project production version. Because user.dir is changing. How else can this be done?
I have written a piece of software that requires me to open and close an executable jar file.
At the moment I have the code able to open the jar with specific arguments
(I have used notepad in the code example as I do not have the Jar file or my original code on me, and needed to test what I had written for this example worked)
The issue I have is when I open and close notepad I get the correct behaviour, however when I try to close my JAR file I am not getting a response.
I have tried killing by the process name under task manager - go to details, the app name, and variants of java, java.exe, javaw etc.
Is it something to do with having launched the jar through CMD?
in which case I have another issue because I have several processes with the exact same name and am not sure how to get the ID when the name is the same.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
// Click on the link below to continue learning how to build a desktop app using WinForms!
System.Diagnostics.Process.Start("http://aka.ms/dotnet-get-started-desktop");
}
//string jarFile = "/JarLocation";
//string jsonlocation = "/jsonlocation";
//string command = $"java - jar {jarfile} -qsArgs {jsonLocation}";
string command = "Notepad";
string processName = "Notepad";
List<int> processIDs = new List<int>();
int[] processID;
Thread testThread;
ThreadStart ts;
private void RunButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Running!");
// METHOD 1 // Launch through CMD directly (in a new thread and try to terminate by process name)
/*
new Thread(() =>
{
LaunchClient();
}).Start();
*/
// METHOD 2 // Generate
/*
foreach (int ID in processIDs)
{
Console.WriteLine($"Process {ID} Created");
}
*/
//Method 3
/*
testThread = new Thread(new ThreadStart(LaunchClient()));
//testThread.Start();
*/
// Method 4
ts = delegate { LaunchClient(); };
}
private void KillButton_Click(object sender, EventArgs e)
{
MessageBox.Show("Killing!");
try
{
// Method 1
Process[] ProcList = Process.GetProcessesByName(processName);
foreach (Process targetProc in ProcList)
{
targetProc.CloseMainWindow();
}
// Method 2
/*
foreach (int ID in processIDs)
{
Process killMe = Process.GetProcessById(ID);
killMe.CloseMainWindow();
}
*/
// Method 3
//testThread.Abort();
//Method 4
//ts.EndInvoke();
}
catch (Exception f)
{
Console.WriteLine("f.StackTrace");
}
}
public void LaunchClient()
{
Thread.CurrentThread.IsBackground = false;
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardInput = true;
//proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.StandardInput.WriteLine(command);
proc.StandardInput.Flush();
Console.WriteLine($"PROCESS ID: {proc.Id}");
processIDs.Add(proc.Id);
//proc.StandardInput.Close();
proc.WaitForExit();
}
}
Sorry to dump a large swathe of code but I thought seeing my implementation of the opening as well as the close would help.
EDIT:
Updated the code sample given to show the 4 different ways I have tried to handle this.
Method 1:
Closing process by name (works for notepad, but not my jar)
2: Trying to pass the process ID back and use that to close the process
(Cant see the ID outside of the thread running the cmd window)
3: using new threadstart (launchclient says 'method name expected')
4: Doesn't open Notepad at all.
If your JAR file is opened with your code, an useful technique is to listen for windowClosing, which happens when the user clicks the X button on Windows (and the equivalent on other systems):
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
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);
}
}
}
}
I am pretty new to Java. I want to create a Java Applet that will allow my JavaScript to pass a commandline to the Java Applet. This will only ever be run on my development machine - no need to remind me what a security issue that is. The use-case is that I have an introspector for my ExtJS app that allows me to display the classes. I want to be able to click a class, pass the relevant pathname to the Applet and have that file open in Eclipse for editing.
I am using Win7x64, jre 1.7
So, to get Eclipse to open the file from the commandline the command is:
D:\Eclipse\eclipse.exe --launcher.openFile C:\mytestfile.js
This works.
I have written the Applet, self signed it and tested the say() method using the code shown below. That works. However when I run the executecmd() method, I don't get any output. If I comment out the whole try/catch block so that I am simply returning the cmd string passed in, the method works. Therefore, I suspect that I have the try catch incorrectly setup and since my Java skills and knowledge of the exceptions are primitive I am lost.
Can anyone help me please? At least to get some output returned, if not how to actually run the command line passed in?
And, I am passing the whole command line because when I have this working I would like to share it (since the Ext introspector is really useful). Other developers will be using different editors so this way they can use it by passing their specific commandline.
Thanks!
Murray
My HTML test page:
<html>
<head>
<meta charset="UTF-8">
<title>Test Run</title>
<script src="http://www.java.com/js/deployJava.js"></script>
<script>
var attributes = { id:'testapp', code:'systemcmd.Runcmd', archive:'runcmd.jar', width:300, height:50} ;
var parameters = {} ;
deployJava.runApplet(attributes, parameters, '1.6');
</script>
</head>
<body>
<p>Hello</p>
<script type="text/javascript">
//alert(testapp.say("Hello test")); // This works
var command = "D:\Eclipse\eclipse.exe --launcher.openFile C:\mytestfile.js";
alert(testapp.executecmd(command)); // Nothing returned at all.
</script>
</body>
</html>
My class:
package systemcmd;
import java.applet.Applet;
import java.io.IOException;
import java.security.AccessController;
//import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
public class Runcmd extends Applet {
private static final long serialVersionUID = -4370650602318597069L;
/**
* #param args
*/
public static void main(String[] args) {
}
public String say(String arg)
{
String msg[] = {null};
msg[0] = "In Say. You said: " + arg;
String output ="";
for(String str: msg)
output=output+str;
return output;
}
public String executecmd(final String cmd) throws IOException
{
final String msg[] = {null};
String output ="";
msg[0] = "In executecmd, cmd="+cmd;
try {
try {
AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws IOException { //RuntimeException,
msg[1] = " Pre exec()";
Runtime.getRuntime().exec(cmd);
msg[2] = " Post exec()";
return null;
}
}
);
} catch (PrivilegedActionException e) {
msg[3] = " Caught PrivilegedActionException:"+ e.toString();
throw (IOException) e.getException();
}
}
catch (Exception e) {
msg[4] = " Command:" + cmd + ". Exception:" + e.toString();
}
msg[5] = " End of executecmd.";
for(String str: msg)
output=output+str;
return output;
}
}
Set Eclipse as the default consumer for .java files and use Desktop.open(File) which..
Launches the associated application to open the file.
Ok, #Andrew. Some progress, thank you!
I set the default program for *.js files to Eclipse and if I double click a file it opens in Eclipse. All good.
I then had success running the following using RunAs Java Application - the test file opened in Eclipse. Getting closer!
public class Runcmd extends Applet {
File file;
private static Desktop desktop;
private static final long serialVersionUID = -4370650602318597069L;
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
System.out.println("hello");
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
}
File file = new File("C:\\sites\\test.js");
// This works if I execute it from the Eclipse RunsAs Java Application.
// ie the file is opened in Eclipse for editing.
// And, if I specify a non-existant file, it correctly throws and prints the error
try {
desktop.open(file);
} catch (Exception ioe) {
ioe.printStackTrace();
System.out.println("Error: " + ioe.toString());
}
}}
However, when I added the following method and ran it via the DeployJava.js (as per my original post above), I get the following output returned with the error appearing whether or not the jar is self signed.
Started: , Desktop is supported , Error:
java.security.AccessControlException: access denied
("java.awt.AWTPermission" "showWindowWithoutWarningBanner")
public static String openfile(String arg) {
String output = "Started: ";
File file = new File("C:\\sites\\test.js");
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
output = output + ", Desktop is supported ";
}
try {
desktop.open(file);
} catch (Exception ioe) {
output = output + ", Error: " + ioe.toString();
}
return output + arg;
}
So, what do I need to add to get around the apparent security issue? I have read the docs and the tutorials and I am going around in circles! There seems to be a lot of conflicting advice. :-(
Thanks again,
Murray
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.