How to Detect workstation/System Screen Lock in ubuntu using java? - java

I'm trying to note down workstation/System screen lock of each employee working in ubuntu OS. I needed to store these record in a DataBase. using JAVA. I have searched all over and got on idea for UBUNTU; But got idea how to do the same in windows OS.

From here:
gnome-screensaver-command -q | grep "is active"
Use the Runtime class to execute that command and read back the result.
EDIT: use grep -q
Here an example how to use it:
public class ScreenSaver {
/*
* Pipes are a shell feature, so you have to open a shell first.
*
* You could use process.getInputStream() to read the output and parse it.
*
* For productive use i would prefer using the Inputstream.
*/
private static final String COMMAND = "gnome-screensaver-command -q | grep -q 'is active'";
private static final String[] OPEN_SHELL = { "/bin/sh", "-c", COMMAND };
private static final int EXPECTED_EXIT_CODE = 0;
public static boolean isScreenSaverActive() {
final Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
/*
* open a shell and execute the command in that shell
*/
process = runtime.exec(OPEN_SHELL);
/*
* wait for the command to finish
*/
return process.waitFor() == EXPECTED_EXIT_CODE;
} catch(final IOException e) {
e.printStackTrace();
} catch(final InterruptedException e) {
e.printStackTrace();
}
return false;
}
public static void main(final String[] args) {
System.out.println("Screensaver is active: " + isScreenSaverActive());
}
}
EDIT: added perl script watching dbus signals. Source:
Gnome Screensaver FAQ
#!/usr/bin/perl
my $cmd = "dbus-monitor --session \"type='signal',interface='org.gnome.ScreenSaver',member='ActiveChanged'\"";
open (IN, "$cmd |");
while (<IN>) {
if (m/^\s+boolean true/) {
print "*** Screensaver is active ***\n";
} elsif (m/^\s+boolean false/) {
print "*** Screensaver is no longer active ***\n";
}
}

Try having a look here, ( Similar duplicate), Detect workstation/System Screen Lock using Python(ubuntu))
GNOME Screensaver FAQ This should be an awesome reference for you to get up to speed. I suppose you are using GNOME.

Related

Entering a series of commands in git bash through java code

Am trying to get a series of commands on git bash one after the other. I can open the terminal through the code but after that wasn't successful with entering anything. For instance this is the code I tried
String [] args = new String[] {"C:\\Program Files\\Git\\git-bash.exe"};
String something="hi how are you doing";
try {
ProcessBuilder p = new ProcessBuilder();
var proc = p.command(args).start();
var w = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
w.write(something);
} catch (IOException ioException){
System.out.println(ioException);
}
Please let know how to be able to do enter a series of commands into git bash through the code.
The problem is that the command git-bash.exe opens the terminal window but the window's input is still the keyboard, so trying to write to the OutputStream that is returned by method getOutputStream(), in class Process does nothing. Refer to this question.
As an alternative, I suggest using using ProcessBuilder to execute a series of individual git commands. When you do that, your java code gets the command output.
Here is a simple example that displays the git version.
import java.io.IOException;
public class ProcBldT4 {
public static void main(String[] args) {
// C:\Program Files\Git\git-bash.exe
// C:\Program Files\Git\cmd\git.exe
ProcessBuilder pb = new ProcessBuilder("C:\\Program Files\\Git\\cmd\\git.exe", "--version");
pb.inheritIO();
try {
Process proc = pb.start();
int exitStatus = proc.waitFor();
System.out.println(exitStatus);
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
When you run the above code, the git version details will be written to System.out.
Also, if the git command fails, the error details are written to System.err.
You need to repeat the code above for each, individual git command that you need to issue.

How to have java run terminal commands on Mac? (Echo command)

How do you have java run commands on Mac? I see some examples of complex commands that is hard to follow. If I wanted to run a simple echo command from java, how would I do that? Not using osascript yet. Just want to see how you would send an echo from java to terminal.
public static void main(String[] args) throws IOException {
ProcessBuilder x = new ProcessBuilder("echo"," hi");
x.start();
}
This is the code I tried, but it does not work.
I think this question can help people who are trying to learn the basics of ProcessBuilder.
I am on Windows so the below code uses Windows echo. I hope you know the Mac echo command so that you can replace my command with yours.
import java.io.IOException;
import java.lang.ProcessBuilder;
public class PrcBldT2 {
public static void main(String[] args) {
// This command is for Windows operating system.
// For MacOS, try: new ProcessBuilder("echo", "hi")
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "echo", "hi");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
try {
Process p = pb.start();
int result = p.waitFor();
System.out.println("Exit status = " + result);
}
catch (IOException | InterruptedException x) {
x.printStackTrace();
}
}
}
Note that each word in the command is a separate string. The echo command output will be redirected to System.out.

Java delete files unix way (unlink header)

I'm having an issue where archival module written in Java fails to clean files shared via smb if opened by network users during cleanup. Below is simplified version of code for file cleanup:
private static boolean moveFile(String sourceFilePath, String targetFilePath) {
boolean fileStatus = false;
File sourceFile = new File(sourceFilePath );
File targetFile = new File(targetFilePath );
if(sourceFile.canRead() && sourceFile.canWrite() ) {
if(targetFile.exists()) {
fileStatus = (new File(targetFilePath)).delete();
if(!fileStatus) {
Logger.ERROR("Target deletion failed");
}
}
fileStatus = sourceFile.renameTo(new File(targetFilePath));
if(!fileStatus) {
Logger.ERROR("RenameTo method failed");
return false;
} else {
Logger.INFO("Move succeeded");
return true;
}
} else {
Logger.ERROR("Cannot read file");
return false;
}
}
It works fine when I test it in two Linux sessions:
session A:
cat -v /dev/zero > sourceFile.txt
session B:
java -jar JavaUnixFileRemovalTest.jar sourceFile.txt targetFile.txt
But fails in production when working with network shares and users.
What I'd like to implement instead is to copy file to archive folder and unlink the header. This way if user still has the file opened he'll continue accessing the content, while name is removed from the file system so nobody else can see the file.
So the question is if there's a way to unlink file header in Unix by native Java means without explicitly calling unlink command
After some research I decided to approach this problem in a bit different way and cast powerful lost magic of the Ancients - that is, use native system C calls with help of JNA (Java Native Access)
Here's an example of the code with some explanations for JNA first-time users:
package com.WeLoveStackOverflow.JavaJNAUnlinkTest;
import java.io.File;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Main {
private static CStdLib cStdLib;
// Here you specify prototypes of native C methods to be called during runtime
// Because unlink(char *path) uses pointer to const char as argument, a wrapper class StringByReference is used to convert data types
// Link to other examples at the end of this post
public interface CStdLib extends Library {
int unlink(StringByReference path);
}
public static void main(String[] args) {
// Here I'm declaring libc usage, but you can link anything. Even your own libraries
cStdLib = (CStdLib)Native.loadLibrary("c", CStdLib.class);
Logger.INFO("Source file: " + args[0]);
Logger.INFO("Target file: " + args[1]);
moveFile(args[0],args[1]);
}
private static boolean moveFile(String sourceFilePath, String targetFilePath) {
boolean fileStatus = false;
File sourceFile = new File(sourceFilePath );
File targetFile = new File(targetFilePath );
if(sourceFile.canRead() && sourceFile.canWrite() ) {
if(targetFile.exists()) {
fileStatus = targetFile.delete();
if(!fileStatus) {
Logger.ERROR("Target deletion failed");
}
}
fileStatus = sourceFile.renameTo(targetFile);
if(!fileStatus) {
Logger.ERROR("RenameTo method failed");
Logger.INFO("Trying to copy file and unlink the original");
// ToDo: add copy method
// That's where we convert String to char*
StringByReference unlinkPath=new StringByReference(sourceFilePath);
int status=cStdLib.unlink(unlinkPath);
if(status==0){
Logger.INFO("Unlink succeeded");
}else {
Logger.ERROR("Unlink also failed");
return false;
}
} else {
Logger.INFO("Move succeeded");
}
} else {
Logger.ERROR("Cannot read file");
return false;
}
return true;
}
}
And class for converting data types:
package com.WeLoveStackOverflow.JavaJNAUnlinkTest;
import com.sun.jna.ptr.ByReference;
public class StringByReference extends ByReference {
public StringByReference() {
this(0);
}
public StringByReference(String str) {
super(str.length() < 4 ? 4 : str.length() + 1);
setValue(str);
}
private void setValue(String str) {
getPointer().setString(0, str);
}
}
So what we've got in the end? A nice Java unlink utility! test scenario: create a text file in session A, open it in less in session B and run java code in session A. Works as expected:
[me#server1 JavaFileTest]$ lsof | grep sourceFile
less 12611 me 4r REG 253,0 0 73 /home/me/JavaFileTest/sourceFile (deleted)
This is the article I used as a reference:
http://jnaexamples.blogspot.com/2012/03/java-native-access-is-easy-way-to.html
It contains other good examples of wrapping data types for C calls
Tips:
Make sure you have both JNA and JNA-platform files in your classpath
JNA 4.4.0 requires GLIBC_2.14. If you're getting this error then
simply downgrade JNA (4.2.2 worked for me)
Exception in thread "main" java.lang.UnsatisfiedLinkError: /lib64/libc.so.6: version 'GLIBC_2.14' not found
File.delete seems to behave as "unlink".
Here's an example
import java.io.*;
public class Main {
public static void main(String args[]) throws InterruptedException, IOException {
File invisibleFile = new File("invisiblefile");
invisibleFile.createNewFile();
FileWriter fw = new FileWriter(invisibleFile);
System.out.println("file created");
Thread.sleep(5000);
boolean deleted = invisibleFile.delete();
if(!deleted) {
System.out.println("error deleting file");
System.exit(1);
}
fw.write("hello");
fw.flush();
System.out.println("file deleted");
// 'ls invisiblefile' does not return anything
// but the file is still held open by the process:
// lsof -p $(ps -ef | awk '/[I]nvisibleFile.java/ {print $2}') | awk '/invisiblefile/ {print "size:" $7; print "inode:" $8}'
Thread.sleep(5000);
fw.close();
System.out.println("file closed");
Thread.sleep(5000);
// after closing file, it is completely gone
System.out.println("end");
}
}
And here's a terminal session to check the program's behaviour:
23:30:07 % java InvisibleFile.java
file created
^Z
zsh: suspended java InvisibleFile.java
23:30:11 % ls invisiblefile
invisiblefile
23:30:14 % fg %1
[1] - continued java InvisibleFile.java
file deleted
^Z
zsh: suspended java InvisibleFile.java
23:30:21 % ls invisiblefile
ls: invisiblefile: No such file or directory
23:30:23 % lsof -p $(ps -ef | awk '/[I]nvisibleFile.java/ {print $2}') | awk '/invisiblefile/ {print "size:" $7; print "inode:" $8}'
size:5
inode:33745509
23:30:30 % fg %1
[1] - continued java InvisibleFile.java
file closed
^Z
zsh: suspended java InvisibleFile.java
23:30:37 % lsof -p $(ps -ef | awk '/[I]nvisibleFile.java/ {print $2}') | awk '/invisiblefile/ {print "size:" $7; print "inode:" $8}'
23:30:42 % fg %1
[1] - continued java InvisibleFile.java
end
23:30:47 %

executing a powershell command in eclipse

I am trying to run a powershell command in eclipse with the following code. The powershell script display the list of installed application on windows. The script works fine when it is executed in powershell. But I am unable to get the output on the console. Could someone please tell me what is the problem here?
import com.profesorfalken.jpowershell.PowerShell;
import com.profesorfalken.jpowershell.PowerShellNotAvailableException;
import com.profesorfalken.jpowershell.PowerShellResponse;
public class TestProcessList {
public static void main(String[] args) throws Exception {
try {
PowerShell powerShell = PowerShell.openSession();
String command = "Get-ItemProperty " +
"HKLM:/Software/Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall/* " +
"| Select-Object DisplayName, DisplayVersion, Publisher, InstallDate " +
"| Format-Table –AutoSize";
PowerShellResponse response = powerShell.executeCommand(command);
System.out.println("Proceses are:" + response.getCommandOutput());
powerShell.close();
} catch (PowerShellNotAvailableException ex) {
throw new RuntimeException("Failed to run PowerShell", ex);
}
}
}
Probably there are thrown some exceptions. Which in your case are not being re-thrown and are consumed (Bad practice).
Change tthe catch block to:
} catch (PowerShellNotAvailableException ex) {
throw new RuntimeException("Failed to run PowerShell", ex)
}
Then you will see what went wrong including its whole stacktrace and possible causes.
UPDATE:
You are actually using piped commands ("|" in execute command string) inside of single command. It wont't work as pipes are not easy to implement in java.
Try out solution basing on following example for command "ps aux | grep java":
import org.apache.commons.io.IOUtils;
public static void main(String[] args) throws Exception
{
Process p1 = Runtime.getRuntime().exec(new String[] { "ps", "aux" });
InputStream input = p1.getInputStream();
Process p2 = Runtime.getRuntime().exec(new String[] { "grep", "java" });
OutputStream output = p2.getOutputStream();
IOUtils.copy(input, output);
output.close(); // signals grep to finish
List<String> result = IOUtils.readLines(p2.getInputStream());
System.out.println(result);
}
Source: https://stackoverflow.com/a/7226858/1688570
As API of the PowerShell library is not known to me, you have to adapt the example to work with PowerShell library by yourself.
Code From PowerShell.java class.
int closingTime = 0;
while (!closeTask.isDone ()
&& !closeTask.isDone()) {
if (closingTime > MAX_WAIT) {
Logger.getLogger(PowerShell.class.getName()).log(Level.SEVERE, "Unexpected error when closing PowerShell: TIMEOUT!");
break;
}
Thread.sleep(WAIT_PAUSE);
closingTime += WAIT_PAUSE;
and
static final int WAIT_PAUSE = 10;
static final int MAX_WAIT = 2000;
This means your command takes more than 2000 milliseconds to close/complete.
I think adding a custom sleep in your code might help. I am not familiar with JPowerShell , you should take a look at PowerShell class. or try with TouDick's answer.
you have to add some wait time. I was executing some commands using java and was not able to print command output on console even though I was using response.getCommandOutput(). So, I tried below by adding wait:
PowerShellResponse response;
Map<String, String> maxWait = new HashMap<String, String>();
maxWait.put("maxWait", "300000");
PowerShell powerShell = PowerShell.openSession().configuration(maxWait);
response = powerShell.executeCommand(yourCommand);
System.out.println(response.getCommandOutput());
The wait time is to wait for maximum time.

How to clear the console?

Can any body please tell me what code is used for clear screen in Java?
For example, in C++:
system("CLS");
What code is used in Java to clear the screen?
Since there are several answers here showing non-working code for Windows, here is a clarification:
Runtime.getRuntime().exec("cls");
This command does not work, for two reasons:
There is no executable named cls.exe or cls.com in a standard Windows installation that could be invoked via Runtime.exec, as the well-known command cls is builtin to Windows’ command line interpreter.
When launching a new process via Runtime.exec, the standard output gets redirected to a pipe which the initiating Java process can read. But when the output of the cls command gets redirected, it doesn’t clear the console.
To solve this problem, we have to invoke the command line interpreter (cmd) and tell it to execute a command (/c cls) which allows invoking builtin commands. Further we have to directly connect its output channel to the Java process’ output channel, which works starting with Java 7, using inheritIO():
import java.io.IOException;
public class CLS {
public static void main(String... arg) throws IOException, InterruptedException {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
}
Now when the Java process is connected to a console, i.e. has been started from a command line without output redirection, it will clear the console.
You can use following code to clear command line console:
public static void clearScreen() {
System.out.print("\033[H\033[2J");
System.out.flush();
}
Caveats:
This will work on terminals that support ANSI escape codes
It will not work on Windows' CMD
It will not work in the IDE's terminal
For further reading visit this
This is how I would handle it. This method will work for the Windows OS case and the Linux/Unix OS case (which means it also works for Mac OS X).
public final static void clearConsole()
{
try
{
final String os = System.getProperty("os.name");
if (os.contains("Windows"))
{
Runtime.getRuntime().exec("cls");
}
else
{
Runtime.getRuntime().exec("clear");
}
}
catch (final Exception e)
{
// Handle any exceptions.
}
}
⚠️ Note that this method generally will not clear the console if you are running inside an IDE.
A way to get this can be print multiple end of lines ("\n") and simulate the clear screen. At the end clear, at most in the unix shell, not removes the previous content, only moves it up and if you make scroll down can see the previous content.
Here is a sample code:
for (int i = 0; i < 50; ++i) System.out.println();
Try the following :
System.out.print("\033\143");
This will work fine in Linux environment
Create a method in your class like this: [as #Holger said here.]
public static void clrscr(){
//Clears Screen in java
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
} catch (IOException | InterruptedException ex) {}
}
This works for windows at least, I have not checked for Linux so far. If anyone checks it for Linux please let me know if it works (or not).
As an alternate method is to write this code in clrscr():
for(int i = 0; i < 80*300; i++) // Default Height of cmd is 300 and Default width is 80
System.out.print("\b"); // Prints a backspace
I will not recommend you to use this method.
If you want a more system independent way of doing this, you can use the JLine library and ConsoleReader.clearScreen(). Prudent checking of whether JLine and ANSI is supported in the current environment is probably worth doing too.
Something like the following code worked for me:
import jline.console.ConsoleReader;
public class JLineTest
{
public static void main(String... args)
throws Exception
{
ConsoleReader r = new ConsoleReader();
while (true)
{
r.println("Good morning");
r.flush();
String input = r.readLine("prompt>");
if ("clear".equals(input))
r.clearScreen();
else if ("exit".equals(input))
return;
else
System.out.println("You typed '" + input + "'.");
}
}
}
When running this, if you type 'clear' at the prompt it will clear the screen. Make sure you run it from a proper terminal/console and not in Eclipse.
Runtime.getRuntime().exec(cls) did NOT work on my XP laptop. This did -
for(int clear = 0; clear < 1000; clear++)
{
System.out.println("\b") ;
}
Hope this is useful
By combining all the given answers, this method should work on all environments:
public static void clearConsole() {
try {
if (System.getProperty("os.name").contains("Windows")) {
new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor();
}
else {
System.out.print("\033\143");
}
} catch (IOException | InterruptedException ex) {}
}
Try this: only works on console, not in NetBeans integrated console.
public static void cls(){
try {
if (System.getProperty("os.name").contains("Windows"))
new ProcessBuilder("cmd", "/c",
"cls").inheritIO().start().waitFor();
else
Runtime.getRuntime().exec("clear");
} catch (IOException | InterruptedException ex) {}
}
This will work if you are doing this in Bluej or any other similar software.
System.out.print('\u000C');
You can use an emulation of cls with
for (int i = 0; i < 50; ++i) System.out.println();
You need to use control characters as backslash (\b) and carriage return (\r). It come disabled by default, but the Console view can interpret these controls.
Windows>Preferences and Run/Debug > Console and select Interpret ASCII control characteres to enabled it
After these configurations, you can manage your console with control characters like:
\t - tab.
\b - backspace (a step backward in the text or deletion of a single character).
\n - new line.
\r - carriage return. ()
\f - form feed.
More information at: https://www.eclipse.org/eclipse/news/4.14/platform.php
You need to use JNI.
First of all use create a .dll using visual studio, that call system("cls").
After that use JNI to use this DDL.
I found this article that is nice:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=5170&lngWId=2

Categories

Resources