Logoff computer using java - java

How to use java to log off windows. It could be using some windows own exe through Runtime(),
or and other methods.It would be more efficient if you could provide some good alternative than using external programs like nircmd.exe .
When I use this code,
String shutdownCmd = "rundll32.exe shell32.dll,SHExitWindowsEx 0";
Process child = Runtime.getRuntime().exec(shutdownCmd);
I get

Do this (-l for logoff here, -r for restart, etc.):
String shutdownCmd = "shutdown -l";
Process child = Runtime.getRuntime().exec(shutdownCmd);
or (0 for logoff here):
String shutdownCmd = "rundll32.exe shell32.dll,SHExitWindowsEx 0";
Process child = Runtime.getRuntime().exec(shutdownCmd);

You can also make a simple .bat file if it's just a file you want.
Open notepad, type the code below, save as *all files, call it 'logoff.bat' or something and it should work.
shutdown -l

You could call the shutdown executable from the Runtime.getRuntime().exec(...) method. Check out this Q&A for details on that: How do I shutdown - restart - logoff Windows via a bat file?

Related

Why doesn't cd command work using Java JSch?

I'm just learning Java and Jsch, and I can get it to run other commands but not cd. The error code returned by the SSHManager sendCommand function is not null, but some unreadable string that is different every time (maybe that means it is null not that familiar with inner workings of Java).
Any idea why not? Similar question here JSch - Why doesn't CD work? but unanswered.
I won't copy and paste the whole SSHManager class here - useful answer with complete code here that I'm trying to follow. Run a command over SSH with JSch
Sample code below:
import SSH.SSHManager;
public class src
{
int ERROR = 0;
public static void main(String[] args)
{
String username = "debian";
String password = "temppwd";
String ipadd = "192.168.7.2";
SSHManager ssh = new SSHManager(username, password, ipadd, "");
ssh.connect();
String out = "";
//this doesn't work, printing output as bytes to show how weird it is
out = ssh.sendCommand("cd Desktop");
System.out.println(out.getBytes());
//some other test commands
out = ssh.sendCommand("mkdir test");
System.out.println(out);
out = ssh.sendCommand("ls");
System.out.println(out);
ssh.sendCommand("logout");
}
}
Output from the Eclipse Console (bin and Desktop are already there in root directory):
[B#b065c63
bin
Desktop
test
Each command executed over SSH "exec" channel (what is behind SSHManager.sendCommand) is executed in its own shell. So the commands have no effect on each other.
To execute multiple commands in the same shell, just use an appropriate syntax of your server shell. Most *nix shells use semicolon or double-ampersand (with a different semantics).
In your case, the double-ampersand would be more appropriate.
cd Desktop && mkdir test && ls
See also Multiple commands using JSch.
Though, if your want to read commands output, you will have problem distinguishing, where output of one commands ends and output of the following commands starts. Let alone if you wanted to check command exit code.
Then it's better to execute each command in its own "exec" channel in a way that does not require a context. In your case that means using full paths:
mkdir Desktop/test
ls Desktop
See also How to perform multiple operations with JSch.
Also as you were going to use file manipulation only, you actually should not execute shell commands at all. Use the standard SSH API for file manipulation, the SFTP.
The question has kind of an answer, in the comments. Every command in sendCommand uses it's own 'pipe', so it disconnects and starts over in each one.
A quick solution would be to send multiple commands in one one sendCommand, such as:
out = ssh.sendCommand("cd Desktop; mkdir test; ls; logout");
But the correct way is to use a session, such as https://stackoverflow.com/a/9269234/290036
I answered a similar question Using java jcabi SSH client (or other) to execute several commands in shell
My open-source API Maverick Synergy has a high-level API to execute multiple commands within a shell. Its currently designed for and works well with bash-type shells.

wget file download ftp waitfor() hangs

I am trying to download a XML file from a FTP server with wget in my Java programm.
I have to wait until it finishes the download.
String command = "WGET -O "
+props.getProperty("xmlFolder")+""+
+ rs.getString("software")
+ ".xml ftp://"+props.getProperty("ftpUser")
+":"+props.getProperty("ftpPasswort")+"#"+rs.getString("xmlPfad");
System.out.println(command);
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
System.out.println("downloaded!");
Without the waitfor() it works perfectly, but with this function it stucks after 2-3 MB are downloaded. Any suggestions?
Have you tried to use the --quiet option for wget?
EDIT 1:
The pipe's write side (child process) might be full.
EDIT 2:
From openjdk-6-src-b20-21_jun_2010
In jdk/src/solaris/native/java/lang/UNIXProcess_md.c (at least for a UNIX system) we can see how Java launches a new child process and how it is using pipe to redirect stdout and stderr from child (wget) to parent process (Java)

Starting a Java application at startup

I have a Java application.
The application has a setting that decides whether or not the application starts at startup.
Currently, I have it this by placing/removing a shortcut in the StartUp items folder.
However, I am wondering if there is a better way to handle this behaviour.
EDIT
Yes, it's Windows. Sorry for not clearing that before.
The application has an UI where the user may trigger actions, also the application runs a few tasks in the background periodically while running.
#Peter, how could I change the registry with code from within the application? Is that approach compatible with all versions of Windows?
Below is a small example snippet of how it can be done from inside your application
static final String REG_ADD_CMD = "cmd /c reg add \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\" /v \"{0}\" /d \"{1}\" /t REG_EXPAND_SZ";
private void exec(String[] args) throws Exception
{
if (args.length != 2)
throw new IllegalArgumentException("\n\nUsage: java SetEnv {key} {value}\n\n");
String key = args[0];
String value = args[1];
String cmdLine = MessageFormat.format(REG_ADD_CMD, new Object[] { key, value });
Runtime.getRuntime().exec(cmdLine);
}
I'm pretty sure this will work with all versions of Windows since they all use the same Startup\Run registry entry.
Hope that helps! :)
Credit
On Windows I have used open source Java Service Wrapper to make our application as window service which you can setup automatic at startup.
What you need to do is to download latest wrapper.exe and create wrapper.config file put all the configuration like Main class any VM arument other parameters in defined standards and create a window service by this exe
Use the Registry to start your program at the startup and then it will be shown in the list provided by msconfig commnd through Run.
Use this registry path
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

java, execute exe from WAR in java code

In my war, I have file exe in WEB-INF\classes\
How can I execute this file in Java code (How can I specify path to this file) ?
command = " ? ";
Process x = p.exec(command);
Te following approach could work:
1) Prepare full path of your executable:
ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/classes/executable");
2) Execute like you would normally do it:
String[] cmd = { fullPath /*[...] arguments */};
Process p = Runtime.getRuntime().exec(cmd);
p.waitFor();
This is a simplified example; you may also want to read more about ProcessBuilder.
This is bad idea. Imagine simply fact that your .war packege should run on almost any server (".war is platform independend") and your .exe file is compiled just for one architecture.
Better should be execute your .exe as external program just for separate platform independent and platform dependent part. Then in java you can test operating system and on this basis run desired externel programm.
Read this link with similar question.
The best way to do find a file's real location inside a web app is to use the ServletContext.getRealPath (see http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getRealPath(java.lang.String))
You can access that object from the session...

Java - get PID of external process by command line in Windows 7

I have Windows 7 32 bit with Java:
How do I get the PID of a process by command line in Windows 7?
I want to kill an application which I only can truly identify by the command line which ran it. We have several Java applications running on that machine. I need to stop specific ones.
To be exact: I need to find tomcat which is run by catalina.bat. What do you think is the best way to do this?
I know of tasklist, but it does not seem to be able to query the command line which started the process. Finding java.exe does not help me. I tried searching for something useful like pgrep/pkill for Windows, with no success.
You could use jps -lv command to determine java process by it's command line options. jps is utility that included in many up-to-date JDKs.
Try in a command prompt:
sc queryex type= service state= all | find "APP"
Where APP is the name of the program. This command will return all services that match that.
Then you can run SC QUERYEX APP and it will return the state and PID number.
Once you have the PID:
TASKKILL /f /pid ###
Where ### is the actual PID
Java, get the PID of the current running process in Windows
This should work on Linux, OSX, Windows, and HotSpot JVM's.
import sun.management.VMManagement;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public static int getCurrentPID() {
try{
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =
(sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =
mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
return (Integer) pid_method.invoke(mgmt);
}
catch(Exception e){
e.printStackTrace();
System.out.println("Failed at getting the process ID");
System.exit(0);
}
}
Invoke it like this:
System.out.println("PID: " + getCurrentPID());
For me it prints the processID: PID: 5728
Sources:
How can a Java program get its own process ID?
http://boxysystems.com/index.php/java-tip-find-process-id-of-running-java-process/
If you just need to kill a specific tomcat from a java application why not coding a simple servlet running inside each tomcat that will responde to a get request with a string that will identify it. Then use another servlet to execute something like:
System.exit(-1);
Finally found something. The solution working for me is called wmic (Windows Management Instrumentation Commandline). This nice tool comes built-in to Windows 7 Pro (mine) and possibly other Windows versions. It provides a quite large variety of actions like listing all the running tasks with every details you can imagine (like their corresponding command line), various hardware info, etc. Exactly what I need.

Categories

Resources