I have to send keystrokes to virtual machine. Task is repetitive(I have to do it 3-4 times a day), but can be easily simulated by sending keystrokes. Actually my VMs have only terminal window (linux based) with SSH session running.
I wrote a small java test program to send the keystrokes.
public class TestRobot1 {
static int keyInput[] = {
KeyEvent.VK_H, KeyEvent.VK_E,
KeyEvent.VK_L, KeyEvent.VK_L,
KeyEvent.VK_O, KeyEvent.VK_ENTER,
};
public static void main(String[] args) throws InterruptedException, AWTException {
Thread.sleep(5000);
Robot robot = new Robot();
for(int i = 0; i < keyInput.length; i++){
robot.keyPress(keyInput[i]);
robot.delay(10);
robot.keyRelease(keyInput[i]);
robot.delay(10);
}
}
}
This program runs successfully on Notepad, VM started in Oracle Virtual Box, and accessed through SSH Session. But it doesn't run when VM is started from hyper-V, though I can SSH to that, and then I can run the program.
I have to select the window, on which this should run, that's why I have included 5 sec wait, so that I can select the correct window in the time. I know that is not very good but, it's a test program.
I have not worked with hiper-v, but I worked with regular remote desktop. I however performed click that makes focus on window using the robot itself. Try this technique. For reference take a look on https://github.com/alexradzin/TypeToPaste
Here is the TypeToPaste site: https://sites.google.com/site/typetopaste/
I recommend to download this application and try it. If it works, examine its code. Otherwise I am sorry...
Please let me know how is it going anyway. I am very curious...
Related
I'm teaching myself Java and I'm using the Deitel book as it came highly recommended and I've hit a bit of a snafu.
So I tried copying over the figure 27.5-8 in the book Java: How to Program. I figured I would need the .5 figure as it's the server and the .7 figure because it's the client. So I made them both in the same project and then combined their main classes (figures .6 and .8) so they when I ran the program it would boot up both the server and the client. But when I tell netBeans to compile and run it opens the windows I have set up for the server and the client but the textFields won't enable (as they're supposed to when they receive a connection.) and as far as I can tell they aren't connecting to each other.
The server.java and client.java files should be exactly the same as they were in the book, so I figure I must have messed up when I blended the main files to boot them both up. Here is my combined main file. Maybe I did something wrong here?
package server_client;
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
Server application = new Server(); //create server
Client applicationClient; //declare client application
//if no command line args
if (args.length==0)
applicationClient = new Client ("127.0.0.1"); //connect to localhost
else
applicationClient = new Client (args[0]); //use args to connect
application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
applicationClient.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
application.runServer(); //run server application
applicationClient.runClient(); //run client application
}//end main
}//end class Main
You are mixing things up. Let's start from the beginning. Firstly, this is how you create a simple UI.
public static void main(String[] args){
JFrame frame = new JFrame(); // This will be holding your future buttons
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Request Generator");
frame.setSize(300, 300); // Size x = 300, size y = 300
frame.setLocationRelativeTo(null); // Puts the frame in the middle of the screen
frame.setVisible(true); // Without this line of code, the frame won't show
}
But I wouldn't recommend creating a UI for test purposes in this case, as it is very time consuming and unnecessary. Use the console instead. You can output anything in the console like this:
System.output.println("Hello, world!");
Or even a variable, like a number.
int number = 10;
System.output.println("Variable number has value: " + number);
Second, I recommend you split up your Client and Server into two separate projects, and starting them separately. Or even better, I can give you a small example of a Client/Server connection if you'd want to. Because, personally, I have never encountered this implementation before.
can be tricky to solve.
There is a utility with windows called netstat which will display all your network connections.
Also learning how to use the debugger will help.
One possibility is that the connection is being established, prior to the GUI checking for it so the GUI doesn't know that the connection is there.
Try starting the server in one application and the client in a different one.
Our products currently using JDK 1.6, so we have to rely on JNotify for file system changes.
However during the test I noticed something that worked perfect in my Win 7 development environment stop working in XP and win server 2003. So I move on to wrote a small test program. Here is what it roughly looks like.
In the main class I only have this:
public static void main(String[] args) {
SyncUtil instance = new SyncUtil();
instance.start();
Scanner s = new Scanner(System.in);
s.nextLine();
}
SyncUtil is a class that extends Threads:
public void run() {
String path = "D:\\testFolder";
int mask = JNotify.FILE_CREATED | JNotify.FILE_DELETED | JNotify.FILE_MODIFIED | JNotify.FILE_RENAMED;
boolean watchSubtree = true;
File file = null;
try {
JNotify.addWatch(path, mask, watchSubtree, new Listener());
} catch (Exception e) {
e.printStackTrace();
}
}
The Listener class don't have any work inside, It just print log.
Now, If I run the above sample on Windows 7 / 8. It will work just fine.
But when I test it on my Win Server 2003, JNotify just stop working and Listener will not print any log at all.
What's more interesting though is if I try to make SyncUtil wait a minute when after its work. If I add:
Thread.sleep(60000);
to the end of the run function to make it wait for 60 seconds.
And instead of monitoring 1 folder, this time I'll monitor 2, I'll call them folder A and B.
What happens on the Win Server 2003 machine in this case is that if I add a file to folder A within the 60s waiting time, JNotify will properly react to the event and print a log. And it will even keep on working even if 60s has passed and the SyncUtil Thread is terminated. But now I add a file to folder B (after the 60s waiting time that is), nothing will be printed.
To sum it up, the symptom is:
1. On win 7 and win 8, JNotify will keep on working disregard of whether or not the thread calls for JNotify.addWatch() is still alive.
2. On win XP and win server 2003, JNotify can properly generate event when The Thread calls JNotify.addWatch() is running. Paths that generated at least one event when that Thread is still alive will continue to be monitored after that thread is terminated. But those paths that didn't generate any event when said thread is alive, will not work after that thread is terminated.
Now knowing this pattern I'm currently using a CountDownLatch to fix the issue, but I'm just really curious why this is happening.
I feel this kind of don't make any sense, where do you think the problem is?
I'm leaning towards the conclusion that maybe windows trigger file system event differently? Do you think this might be the case?
this is very weird, but:
adding a watch is a really quick operation, why are you adding them in a thread?
We know how to force shutdown an computer using Java. For example, the following code works fine for force shutdown:
public static void main(String arg[]) throws IOException{
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("shutdown -s -t 0");
System.exit(0);
}
Now, suppose if I want to force startup a computer (which is in shut down state), at a particular time, is it possible to do in Java or any other language?
You need something to trigger the startup. The best way to trigger this is Wake On Lan.
If you want to do this in Java, this might be a good resource.
In addition to wake on lan, there are IPMI devices that run on some server-grade hardware that is connected to the motherboard and can control power as well as provide serial console output over a network connection. This computer is running all the time, but I'm not familiar with any you can load your own code onto.
You can control this device remotely to power control the server that is off from any language including java.
http://en.wikipedia.org/wiki/Intelligent_Platform_Management_Interface
If your BIOS supports Advanced Power Management (APM) version 1.2 or later, it should be possible to wake it from sleep/standy or hibernation based on a timer. On Windows an end user can do this through Task Scheduler, and if you wish to do it programmatically you can use the Task Scheduler interfaces.
I don't know how you would do this through Java, but here is some example C code that will create a task to wake the computer up 2 minutes in the future:
#include <mstask.h>
#include <time.h>
int main() {
HRESULT hr = CoInitialize(NULL);
if (SUCCEEDED(hr)) {
ITaskScheduler *scheduler;
hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void**)&scheduler);
if (SUCCEEDED(hr)) {
ITask *task;
hr = scheduler->NewWorkItem(L"Wake Timer", CLSID_CTask, IID_ITask, (LPUNKNOWN*)&task);
if (SUCCEEDED(hr)) {
WORD index;
ITaskTrigger *trigger;
hr = task->CreateTrigger(&index, &trigger);
if (SUCCEEDED(hr)) {
time_t t = time(NULL) + 120;
struct tm *ltime = localtime(&t);
TASK_TRIGGER triggertime;
memset(&triggertime, 0, sizeof(triggertime));
triggertime.cbTriggerSize = sizeof(TASK_TRIGGER);
triggertime.wBeginYear = ltime->tm_year+1900;
triggertime.wBeginMonth = ltime->tm_mon+1;
triggertime.wBeginDay = ltime->tm_mday;
triggertime.wStartHour = ltime->tm_hour;
triggertime.wStartMinute = ltime->tm_min;
triggertime.TriggerType = TASK_TIME_TRIGGER_ONCE;
trigger->SetTrigger(&triggertime);
trigger->Release();
}
task->SetFlags(TASK_FLAG_DELETE_WHEN_DONE|TASK_FLAG_SYSTEM_REQUIRED|TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
task->SetAccountInformation(L"", NULL);
IPersistFile *file;
hr = task->QueryInterface(IID_IPersistFile, (void**)&file);
if (SUCCEEDED(hr)) {
file->Save(NULL, TRUE);
file->Release();
}
task->Release();
}
scheduler->Release();
}
CoUninitialize();
}
return 0;
}
Assumedly if you can do this on Windows, there must be equivalent APIs for other operating systems.
I did manage to find a similar question floating around on the internet, so I'll post the links here to see if you find it helpful. (this was the thread I found: http://www.coderanch.com/t/440680/gc/interact-Windows-Task-Scheduler-Java)
First of all though, I might add that Java is a language that must run in a Virtual Machine - there are no two ways around it. I'm not well versed in 'low-level' programming, such as programming at closer to BIOS level, which is sort of where we are heading with this.
As the question was explicitly about Java, the best I could come up with from research, is (if you're really wanting to use Java for something), using the JAVA-COM (JACOB) http://sourceforge.net/projects/jacob-project/ which allows you to hook into the Windows Task Scheduler http://msdn.microsoft.com/en-us/library/aa383581%28VS.85%29.aspx via the COM language (AF
As far as I am aware, because Java needs to be in a virtual machine to run, there would be no way of getting it to do an action such as turning on a PC - let's not even get into issues of whether such an action would require administrator or above privileges.
Hope that helps.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java/shellscript code to find out if a jar file is already running on current machine
I would love to get a cross-platform solution for this, but even if it's unix only- that would be fine.
The simple solution would be to do this from the shell (Pseudocode)(if ps -aux | grep myJar | print {awk 2}.contains myPID, don't run myProgram.
Now unfortunately our linux team doesn't want a script like that running in production since it can (admittedly) have undesired behaviors.
So what I need is to be able to have a file run, and when it runs see if another program is running. If the program is already running and it's below that time limit, it should prevent the program from running.
A bit of an example:
Myprog.jar -- timeout 5 min
Myprog.jar is in a cron that gets called every 4 minutes,
the first time it's called it launches, the second time it's called it's still running, but since it's not over the timeout, it's fine.
If it's still running when the third check comes through (at 8 minutes into execution) it's killed, and its process is replaced by itself afterwards.
If someone can help me understand how to do this (We've been trying to set up a lock file with limited success)
Thanks!
You could make your program open a dummy file for writing with a FileWriter when your program starts, and keep the file open until the program is finished.
When you now start a second instance of your program, it will also try to open this file for writing, which will throw an IOException, because only one process can have a write handle to a file at the same time.
You could use a port as a semaphore. See this question for more info on that. I think a port would be a good cross-platform solution
You can create a temporary file on a fixed location.
private static final File LOCK_FILE = new File("app.lock");
public static boolean checkIfAlreadyRunning()
{
return LOCK_FILE.exists();
}
public static void createLockFile()
{
LOCK_FILE.createNewFile();
Runnable shutDown = new Runnable()
{
public void run()
{
try
{
LOCK_FILE.delete();
} catch (Exception e) { /* Sad but true */ }
}
};
Runtime.getRuntime().addShutdownHook(new Thread(shutDown));
Thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Exception e)
{
shutDown.run();
System.exit(-1);
}
});
}
I had exactly the same problem, and it can be pretty tricky to solve. Both File and Socket based approaches can be made to work, but it gets really tricky on some OS's (think of Windows with multiple users in multiple terminal server sessions etc.).
First, determine the scope where you want only one instance. Then decide on a solution.
The ServerSocket method with a fixed port number will allow you one instance per machine (maybe not exactly what you want).
The locking file approach can be tailored to create the locking file in the users temp directoy, so it gives one instance per session/user.
I personally use a combined approach where the locking file specifies a random port and a second instance connects to that port to pass command line parameter to the running instance.
I just wanted to know if there is some way to switch between console mode and graphical mode. I am using java on swing.
I'd like to know if I can type something in the shell to go to a console mode, then type something to go back to the desktop. Or if I can press some key at boot time, or something.
The idea is to make my server run in console mode, but have desktop available when I want to easier make my tasks.
You can use java.awt.GraphicsEnvironment.isHeadless() to check whether the environment where your program is running supports GUIs or not:
public static void main(String[] args){
if (GraphicsEnvironment.isHeadless()){
// Run console mode
} else {
// Start in GUI mode
}
}
If I were you, though, I'd make this a command-line switch so you can use the console mode in graphic environments, too. For maximum convenience, this would be a non-mandatory option which defaults to some kind of "auto" option, which uses the isHeadless check, like:
public static void main(String[] args){
final List<String> arguments = Arrays.asList(args);
final int modeIndex = arguments.indexOf("-mode");
final String mode = modeIndex == -1 ? "auto" : argument.get(modeIndex);
if ("auto".equals(mode)) runAuto();
else if ("console".equals(mode)) runConsole();
else if ("gui".equals(mode)) runGui();
else System.err.println("Bad mode: " + mode);
}
private static void runGui(){ ... }
private static void runConsole(){ ... }
private static void runAuto(){
if (GraphicsEnvironment.isHeadless()) runConsole();
else runGui();
}
(TODO: Add error handling, remove magic string literals, etc.)
So, start your program with java YourMainClass or java YourMainClass -mode auto and it makes an educated guess whether you want GUI or console, use java YourMainClass -mode console to force console mode, or java YourMainClass -mode gui to force GUI mode.
You can divide the project in two: the server and the GUI. You can run your server as a service (Windows) o daemon (Linux) and when you want the GUI, you have to launch and operate with it.
It´s like applications as MlDonkey, Ettercap, etc.
You can pass parameters on the command line and examine them in main(String[] args). They'll end up in args. So the most simply way is to check for args.length > 0 && "-c".equals (args[0]) to tell the program to run in console mode and to open a UI otherwise.
Another option is to write two main() methods (in different classes) and use the right one.
In the program you can define commands to hide the GUI. Something like gui.setVisible(false) should do the trick, it hides the window referenced by gui and all elements of it.
You could create a command line command that starts a GUI wizard that enables you to easily create the components/ configuration you want, and then enable the GUI to pass the complicated instruction back into your single application thread. Whether it is useful to have the GUI component destroyed after you have used it, or just hidden, is a decision you will have to make, regarding how often you will be using the GUI component.