How can I target a process without executing it? - java

I've come across the following code recently:
Process proc1 = Runtime.getRuntime().exec("C:\\Program Files (x86)\\...");
This is working great. However, an intresting problem. This code actually opens a new instance of the specified process and stores it to the object. It doesn't target that process if its already running and store it to the object. I'm guessing thats the .exec() function call which is doing that. How can I target an already active process and store it to my Process object without opening a new instance?
Note: I tried the obvious answers, Process proc1 = new Process("name"); Eclipse says Process cannot be instantiated. I did lookup the Runtime class in the javadoc. As far as I can tell, there is no obvious method that does what I'm trying to achieve. Seems like a simple qustion, I'm sure its been asked before but I couldn't find the answer anywhere which is why I'm asking here. I may be using the wrong terminology which is why.
EDIT:
I'm on Windows 10
My objective is to attatch the process of the game Minecraft to a Process object. Then, I want to move my character forward using robot.keyPress(KeyEvent.VK_W);. I can't just open the process minecraft because all that would do is open the launcher minecraft.exe and then I'd be on a "welcome" screen.

As you can surmise from the Process docs, the process object is created when you create a child process from your code. You can manage the process by using this object, but the other processes out there running are for your OS to manage (or the processes they have affinity to). You'll have to interact with the OS to do anything with them.
An example for finding and killing a process in Windows can be found in this answer.

Related

Environment sharing between request threads in Google App Engine

I have noticed that when I create a new thread using the request thread factory provided by GAE then the new thread has the same Environment as the parent thread. (The identityHashCode of the current environment is the same in both threads.)
On the one hand, this is nice because the newly created thread starts with the same context as the parent.
The problem is that the Environment is not immutable. It contains the ".currentNamespace" attribute which is used in namespace handling. If one of the threads changes the current namespace it is applied on all threads which is clearly not what I want.
My idea to fix this was that I created an own Environment implementation and when a new thread is created I copy the content of the current environment into this new environment and set this environment as current on the new thread. So the new thread starts with the same context but it can independently change later.
This solution worked during initial testing but then I run into a problem
Caused by: java.lang.ClassCastException: MyEnvironmentImplementation cannot be cast to com.google.apphosting.runtime.ApiProxyImpl$EnvironmentImpl
at com.google.apphosting.runtime.ApiProxyImpl.log(ApiProxyImpl.java:67)
I have no access to the code of com.google.apphosting.runtime.ApiProxyImpl but it is clear that this method tries to cast the interface it received into its own implementation class without checking the type.
I find this strange because there is a void setEnvironmentFactory(ApiProxy.EnvironmentFactory factory) in the ApiProxy so it is expected that someone might use a different implementation of the Environment interface than the default one.
Is there another way to use different namespaces in different request threads?
Is this unchecked casting considered a bug or is it fundamentally wrong to use my own Environment implementation?
I use app engine standard with 1.9.84 of the java sdk.
Edit:
It is actually documented that "This should not be used from user-code." on the
ApiProxy.setEnvironmentForCurrentThread() and ApiProxy.setEnvironmentFactory() methods. So my suggested workaround is not expected to work. You shouldn't try something like it either.
No need to use Google API threads. Do not let Google API's cause you problems. Do this yourself outside of the browser as I describe here.
Write a program that sub-classes your browser, and subclass each window that is opened. Then run a javascript on each page that saves your result to the location bar where it is easy to collect it later. Then collect that information from the location bar and then put the previous (which was in the location bar) back into it so that it will be seen as being the same as it was before.
If you want to use that data in a different web page then put it there via your separate program.
Each opened browser window could theoretically be running a separate google api process.
With your program subclassing all of the browser windows separately, have your program to share information between them without the google api getting confused.
Like this:
Write a program (in VB6 sp5 I did this years ago. Never use any later version of Visual Studio for anything. In C++11 this should work.).
Using FireFox as a browser for this example.
(1) Have your program start and Subclass FireFox.
(2) Have your program tell Firefox to open up a new window (might need to make this a FireFox "new tab" or maybe not).
(3) Tell your program to get the pre-handle of the newly opening window. Do this quickly and keep trying (up to 30 seconds if you have an overloaded operating system) until you get the pre-handle, then assign a new Window's handle to that new window or new tab.
(4) Use that new handle and send a javascript to the address bar (minus the "j"), meaning that you send an entire "avascript..." to that address bar, then add the previous "j" since if FireFox detects that you placed any command into the addressbar with the entire word "javascript" it will stop you from doing some things (if I recall correctly).
(5) Run that javascript obtaining from or placing into each page your changes.
(6) The web pages in the browser, having the javascript running in them do part of the work.
(7) No need to use Google API threads.

Want to know the exact comment

how to run a jar file in background in windows cmd
this below jar file cmd i want to run in background
java -Djavax.net.ssl.trustStore=cacerts_appedo_agent-Djavax.net.ssl.trustStorePassword=changeit -jar appedo_tomcat_agent_2.0.063.jar
You can't do this in a platform-independent manner.
In Unix/Linux, you would call the fork() system call, which duplicates your process. With Java, that means duplicating the entire JVM. Then, you'd have to figure out whether it's the parent process or the child process, which you can determine from the process ID that the fork() call gives you. If it's the parent process, you exit. If it's the child process, you have to close standard input, standard output and standard error.
In Windows, there appears to be the FreeConsole function, but I know next to nothing about Windows programming.
So conceivably, you could write a JNA library that figures out on which platform you are, and invokes the appropriate calls to achieve this. But it's probably not the best idea to get rid of the console window when starting a Java application.
Use javaw, although you won't get any console output either, which is inconvenient.

Launch program from batch file generated by Java

I made a way to make my program, written in Java, update itself. The final JAR is wrapped in a EXE file, through Launch4j tool.
You need to know this piece of code:
System.getProperty("java.class.path").replaceAll("\\;\\.$", "")
gives me the actual path of the EXE. I tested it and it seems to be always working. This is important for the problem.
Now, basically the program pings a webpage and reads a series of values, which one of them is the latest version of the program. If it's greater, the program notifies the user for the update. So, the program downloads the remote data (updated EXE file) and stores them in the current running EXE file, whose filename is obtained through the method explained above. It works, but here comes the problem.
I could simply launch the downloaded EXE file and System.exit the current one, but I cannot do this, because my program works with smart cards: if two or more programs use the same smart cards, the new one won't work (I don't know why, I even restart the provider each time, but this is another story). So I prevent users from starting multiple istances of the program.
(My customers are not so smart to manually open the program each time they need it, so I needed to override the close button to make it stay in traybar, and wake up everytime it is needed. I even make it starts when Windows boots up).
So I have to close the current instance of the program, and launch again.
How I do this? I write a batch file which will basically look like this:
#echo off
taskkill /f /pid <pid of the exe program>
ping 127.0.0.1 -n 3 (this is a way to wait. I will eventually lower the waiting)
C:\Users\Mark\Desktop\program.exe (string generated by the method above. It should launch the program)
exit
Once written to disk, I execute it through Java:
Runtime.getRuntime().exec("cmd /c start " + batchFile.toString());
"batchFile" variable is a File object.
The problem is that the new downloaded program is not launched. A console window appears, shows the result of "taskkill" and "ping" (I will eventually mute them), but the program does not start. If I launch the batch file manually, it does.
Why? I really don't understand this behaviour.
Do you have any advice?
Thanks in advance!
TL;DR version:
The batch file executed by my Java program does not start the exe file written in it. Why?
I have the feeling you are trying to overwrite an executable file (EXE) that is currently running. AFAIK Windows locks such files and thus your updates should never happen.
To resolve your problem: I would split your application in two.
One part ensures the other part has the latest version, then executes that latest version.
For Java, something like this has been developed many years ago as WebStart technology, was marked as deprecated for Java 9 and removed thereafter. Meanwhile there is the project https://openwebstart.com/ that you might want to check out.

Controlling Process Name of my Jar

I wanted to know is there any way I could control the name the process my jar is starting, i.e,
I created a .jar file in java and whenever I am clicking on it, it is causing a process named javaw.exe and I want to control this name.
I want to do so because when I click on my jar file then if it already running it should stop and a new one should start, i.e., I want to run a new thread (process) everytime I click on it by stopping the previous one.
If I kill the process named javaw.exe, all processes with name javaw.exe would die (if I am running more than one program) . So, I need to change its name.
Plz help.
Thanks !
There's nothing wrong with javaw running. From the documentation:
The javaw command is identical to java, except that with javaw there is no associated console window. Use javaw when you don't want a command prompt window to appear. The javaw launcher will, however, display a dialog box with error information if a launch fails for some reason.
Ultimately, javaw runs your program without a console window. Changing that name could lead to some serious issues later, so you'd want to keep that particular program name.
Why reinvent the wheel? There are already standard ways to prevent two copies of the same program from running. Typically it involves creating a "flag" file, since filesystems guarantee that directory updates are atomic. On UNIX-like systems, the file would be /var/run/program-name.pid. If it already exists, then the second copy will exit with an error.
You could setup a controller process, that manages your instances:
First you try to connect to the controller on localhost via tcp/ip at a specific port (your programs "name" from now) and if sucessful, you send a message like 'new instance started' to that controller. If the connection was not sucessful, you start a new controller-thread in the current vm (and send the message again to this thread)
the controller loops, waiting for messages and if one matches 'new instance started', it does what you describe.
such a controller can be built easily using a simple ServerSocket, a small HTTP-server or many other messaging libs.

Opening more than one of the same Mac Application at once

I'm developing a Mac App in Java that logs into any one of our client's databases. My users want to have several copies of this program running so they can log into a couple clients at the same time, rather than logging out and logging back in.
How can I allow a user to open several copies of my App at once?
I'm using Eclipse to develop, and Jarbundler to make the app.
Edit: More Importantly, is there a way to do so in the code base, rather than have my user do something funky on their system? I'd rather just give them a 'Open New Window' menu item, then have them typing things into the Terminal.
You've probably already gotten enough code that you don't want to hear this, but you should really not be starting up two instances of the same application. There's a reason that you're finding it so difficult and that's because Apple doesn't want you to do it.
The OSX way of doing this is to use the Cocoa Document-based Application template in XCode. Apple Documentation: choosing a project.
This is something users are very accustomed to, and it works just fine. FTP programs, IRC clients, and many other types already use different "document" windows to point to different servers or channels. There's nothing inherently different about pointing to different databases.
Depending on how much code you've written, and how your application is designed, this may be pretty much impossible to implement without starting over. Developers who are encountering this problem during design phase, however, should definitely take Apple's advice.
From the Terminal, I can run
open -n -a appName.app
Then from Applescript, I can run
tell application "Terminal"
activaate
do script "open -n -a appName.app"
end tell
Then from Java, I can execute that script. Then, I can stuff that Java code into an Action. Then, stuff that action into a menu item that says "Open New Window".
That's what I'm going with for the moment. Now I just need to get the appName.
From the Terminal (or in a script wrapper):
/Applications/TextEdit.app/Contents/MacOS/TextEdit &
Something like that should work for you.
To do this in Java:
String[] cmd = { "/bin/sh", "-c", "[shell commmand goes here]" };
Process p = Runtime.getRuntime().exec (cmd);
If you are developing it in swing, you should just be able to instantiate the top Frame to create a new window.

Categories