How can I copy a Java object (with a couple of fields) to my clipboard in Java, and what is the best way to store these fields?
I have a simple object with a ΗashΜap for storage.
Also, I created a selection for this object, which it implements both Transferable and ClipboardOwner, as well as a DataFlavor for it.
What I'm trying to do is copy this object and paste it in another application. Keep in mind that I don't have access to the source code of this application, so I have to transfer this object in this particular way. Let's say this application is requiring these following fields:
Info (String)
Text (String in UTF-8 Format)
However, copying and pasting this object to the other application doesn't seem to work.
Below you can see my classes:
MyObject:
import java.util.HashMap;
public class MyObject {
private HashMap<Object, Object> data;
public MyObject()
{
data = new HashMap<Object, Object>();
}
public void setData(Object field, Object value)
{
data.put(field, value);
}
}
MyObjectFlavor:
import java.awt.datatransfer.DataFlavor;
public class MyObjectFlavor extends DataFlavor {
public MyObjectFlavor()
{
super(MyObject.class, null);
}
}
MyObjectSelection:
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class MyObjectSelection implements Transferable, ClipboardOwner {
final static DataFlavor myObjectFlavor = new MyObjectFlavor();
final static DataFlavor[] supportedDataFlavors = { myObjectFlavor };
private MyObject myObject;
public MyObjectSelection(MyObject myObject)
{
this.myObject = myObject;
}
public Object getTransferData(DataFlavor dataFlavor)
throws UnsupportedFlavorException, IOException
{
if (!isDataFlavorSupported(dataFlavor)) {
throw new UnsupportedFlavorException(dataFlavor);
}
// Passing data in a ByteArrayOutputStream.
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
objectStream.writeObject(myObject);
return byteStream.toByteArray();
}
public DataFlavor[] getTransferDataFlavors()
{
return supportedDataFlavors;
}
public boolean isDataFlavorSupported(DataFlavor dataFlavor)
{
for (int i = 0; i < supportedDataFlavors.length; i++) {
if (supportedDataFlavors[i].equals(dataFlavor)) {
return true;
}
}
return false;
}
public void lostOwnership(Clipboard arg0, Transferable arg1)
{
// Lost ownership.
}
}
Finally, my Main class is:
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class Main {
public static void main(String args[]) throws IOException {
MyObject myObject = new MyObject();
MyObjectSelection selection = new MyObjectSelection(myObject);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard ();
String myUtfString = "This is a String in UTF-8";
myObject.setData("Info", "This is a Java Object.");
myObject.setData("Text", new ByteArrayInputStream(myUtfString.getBytes("UTF-8")));
clipboard.setContents(selection, selection);
}
}
I'm sorry for the long post, but I think providing all classes will help. I hope this question is not specific.
Thanks in advance!
Related
I am trying to build a Kafka source connector for audio files. from my understanding, I have to read the audio files as a Byte array.
I am using the confluent-quick-start project as a skeleton for development. the connector is not working, I can't tell why, because I don't know how to make it print logs for errors. I need help to make this work, I am not an expert in java, you can probably tell by the code.
is my approach correct? and do I have to do anything to the pom.xml file or just leave it as is?
I have examined previously available projects and tried to apply the concept for audio files. the following are the classes:
AudioSourceConnectorConfig
package org.othman.example;
import org.apache.kafka.common.config.AbstractConfig;
import org.apache.kafka.common.config.ConfigDef;
import org.apache.kafka.common.config.ConfigDef.Type;
import org.apache.kafka.common.config.ConfigDef.Importance;
import java.util.Map;
public class AudioSourceConnectorConfig extends AbstractConfig {
public static final String FILENAME_CONFIG="fileName";
private static final String FILENAME_DOC ="Enter the name of the audio file";
public static final String TOPIC_CONFIG = "topic";
private static final String TOPIC_DOC = "Enter the topic to write to..";
public AudioSourceConnectorConfig(ConfigDef config, Map<String, String> parsedConfig) {
super(config, parsedConfig);
}
public AudioSourceConnectorConfig(Map<String, String> parsedConfig) {
this(conf(), parsedConfig);
}
public static ConfigDef conf() {
return new ConfigDef()
.define(FILENAME_CONFIG, Type.STRING, Importance.HIGH, FILENAME_DOC)
.define(TOPIC_CONFIG, Type.STRING, Importance.HIGH, TOPIC_DOC);
}
public String getFilenameConfig(){
return this.getString("fileName");
}
public String getTopicConfig(){
return this.getString("topic");
}
}
AudioSourceConnector
package org.othman.example;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.kafka.common.config.ConfigDef;
import org.apache.kafka.connect.connector.Task;
import org.apache.kafka.connect.source.SourceConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AudioSourceConnector extends SourceConnector {
private static Logger log = LoggerFactory.getLogger(AudioSourceConnector.class);
private AudioSourceConnectorConfig config;
private Map<String, String> configProps;
#Override
public String version() {
return VersionUtil.getVersion();
}
#Override
public void start(Map<String, String> map) {
//config = new AudioSourceConnectorConfig(map);
this.configProps = new HashMap(map);
//TODO: Add things you need to do to setup your connector.
}
#Override
public Class<? extends Task> taskClass() {
//TODO: Return your task implementation.
return AudioSourceTask.class;
}
#Override
public List<Map<String, String>> taskConfigs(int maxTasks) {
return (List) IntStream.range(0, maxTasks).mapToObj((i) -> {
return new HashMap(this.configProps);
}).collect(Collectors.toList());
//TODO: Define the individual task configurations that will be executed.
}
#Override
public void stop() {
//TODO: Do things that are necessary to stop your connector.
this.configProps=null;
}
#Override
public ConfigDef config() {
return AudioSourceConnectorConfig.conf();
}
}
AudioSourceTask
package org.othman.example;
import org.apache.kafka.connect.data.Schema;
import org.apache.kafka.connect.source.SourceRecord;
import org.apache.kafka.connect.source.SourceTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class AudioSourceTask extends SourceTask {
static final Logger log = LoggerFactory.getLogger(AudioSourceTask.class);
AudioSourceConnectorConfig config;
private Process inputProcess;
byte [] audioFile;
#Override
public String version() {
return VersionUtil.getVersion();
}
#Override
public void start(Map<String, String> map) {
//TODO: Do things here that are required to start your task.
// This could be open a connection to a database, etc.
this.config = new AudioSourceConnectorConfig(map);
try{
audioFile = Files.readAllBytes(Paths.get(this.config.getFilenameConfig()));
// this.inputProcess = (new ProcessBuilder((new String[]{this.config.getFilenameConfig()}))).redirectError().start();
}
catch(IOException e){
System.out.println("ERROR WHILE TRYING TO READ AUDIO FILE...");
e.printStackTrace();
}
}
#Override
public List<SourceRecord> poll() throws InterruptedException {
//TODO: Create SourceRecord objects that will be sent the kafka cluster.
final ArrayList<SourceRecord> records = new ArrayList<>();
SourceRecord record;
for (int i=0;i < audioFile.length - 1;i++) {
record= new SourceRecord(null, null, this.config.getTopicConfig(), 0, Schema.BYTES_SCHEMA, audioFile[i]);
records.add(record);
}
return records;
}
#Override
public void stop() {
//TODO: Do whatever is required to stop your task.
}
}
I am trying to save obj in files but java.io.NotSerializableException error doesnt allow me to do it.
This is my code:
import Estrategia.Gestor_nivel;
import Resources.Exceptions.DuplicateLevelsId;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import pp_epoca_normal.Gerir_jogo;
public class Teste {
public void guardar_ficheiro(Object obt) {
Gerir_jogo teste = (Gerir_jogo) obt;
System.out.println("sad---- " + teste);
Gestor_nivel sad;
try {
ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream("teste.dat"));
ObjectOutputStream objOut1 = new ObjectOutputStream(new FileOutputStream("teste1.dat"));
objOut.writeObject(teste);
objOut1.writeObject(teste.getObjetos());
sad = (Gestor_nivel) teste.getLevel(0);
objOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void ler_ficheiro() throws FileNotFoundException, IOException, ClassNotFoundException, DuplicateLevelsId {
Gerir_jogo asd;
ObjectInputStream mySecondStream = new ObjectInputStream(new FileInputStream("teste.dat"));
ObjectInputStream mySecondStream1 = new ObjectInputStream(new FileInputStream("teste1.dat"));
asd = (Gerir_jogo) mySecondStream.readObject();
asd.setObjetos((Object[]) mySecondStream1.readObject());
System.out.println("leu--");
mySecondStream.close();
mySecondStream1.close();
}
}
Class gerir jogo
import Container.Contentor;
import Estrategia.Gestor_nivel;
import Resources.Exceptions.DuplicateLevelsId;
import Resources.GameContainerContract;
import Resources.GameLevelContract;
public class Gerir_jogo extends Contentor implements GameContainerContract {
private String nome_jogo;
private boolean mode_jogo_depuracao;
public Gerir_jogo(String nome_jogo, boolean mode_jogo) {
this.nome_jogo = nome_jogo;
this.mode_jogo_depuracao = mode_jogo;
}
#Override
public boolean addNewLevel(GameLevelContract glc) throws DuplicateLevelsId {
Gestor_nivel a;
boolean asd = false;
for (Object objetos : this.getObjetos()) {
a = (Gestor_nivel) objetos;
if(objetos != null)
if (a.getId() == glc.getId()) {
asd = true;
}
}
if (asd == false)
return super.addObject(glc);
return false;
}
#Override
public boolean removeLevel(GameLevelContract glc) {
return super.Encontrar_objeto(super.removeObject(super.findObject(glc)));
}
#Override
public GameLevelContract getLevel(int i) {
return (GameLevelContract) super.getObject(i);
}
#Override
public int getSize() {
return super.getCont();
}
#Override
public boolean getDebugMode() {
return this.mode_jogo_depuracao;
}
#Override
public void setDebugMode(boolean bln) {
this.mode_jogo_depuracao = bln;
}
#Override
public void setName(String string) {
this.nome_jogo = string;
}
#Override
public String getName() {
return this.nome_jogo;
}
Can someone help me please?
I really need to put this saving and reading files and what is inside them
Error:
java.io.NotSerializableException: pp_epoca_normal.Gerir_jogo
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at Gravar_ler_ficheiro.Teste.guardar_ficheiro(Teste.java:34)
at pp_epoca_normal.PP_epoca_normal.main(PP_epoca_normal.java:77)
I really dont know what to do
Your class Gerir_jogo must implements the interface Serializable. Please, take a look at this tutorial.
Edit 1
Your class does not implements it, so, change if for:
import java.io.Serializable;
public class Gerir_jogo extends Contentor implements GameContainerContract, Serializable {
Implement Serializable on Gerir_jogo class.
Change class declaration as:
import java.io.Serializable;
public class Gerir_jogo extends Contentor implements GameContainerContract, Serializable {
To serialize java object means to stream the byte information as non-static states of the object to external file. Here the class must be implemented by the interface "Serilizable".
Here I have replied with a code, which copies the States as id, name & sal of the class "Employee" to an external file present at the destination "D:\Object\States.txt". Here its not readable.
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class Employee implements Serializable {
int id;
String name;
double sal;
public Employee(int id, String name, double sal) {
super();
this.id = id;
this.name = name;
this.sal = sal;
}
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", sal=" + sal + "]";
}
public static void main(String[] args) throws Exception {
Employee e1 = new Employee(101, "Mr. S.V. Roshan", 45000.0D);
FileOutputStream fout = new FileOutputStream("D:/Object/State.txt");
ObjectOutputStream out = new ObjectOutputStream(fout);
out.writeObject(e1);
out.flush();
out.close();
fout.flush();
fout.close();
System.out.println("Object serialized successfully!");
}
}
I think, It may help you..!
The below code is for putting a kryo serialised object into an Hazelcast's Imap instance followed by retrieving. On retrieving the object it throws an error named:
com.hazelcast.nio.serialization.HazelcastSerializationException: com.esotericsoftware.kryo.KryoException: java.io.EOFException: Unexpected end of ZLIB input stream
My code is given below.
package hazelcast2;
import java.util.Scanner;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.SerializerConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.ISet;
public class zlibtry {
public static Config config;
public static ClientConfig cfg;
public static HazelcastInstance hz;
public static IMap<String,MyDataObject> mapItemCount;
public static void main(String[] args) throws Exception{
// Scanner obj = new Scanner(System.in);
config= new Config();
config.setProperty("hazelcast.elastic.memory.enabled" , "true");
config.setProperty("hazelcast.elastic.memory.total.size", "60G");
config.setProperty("hazelcast.elastic.memory.chunk.size","2");
MapConfig mapConfig = new MapConfig();
mapConfig.setInMemoryFormat( InMemoryFormat.OBJECT );
//config.getNetworkConfig().setPort(5701);
//config.getNetworkConfig().setPublicAddress("127.0.0.1");
config.setProperty("address","127.0.0.1");
SerializerConfig productSerializer = new SerializerConfig()
.setTypeClass(MyDataObject.class).setImplementation(new ProductKryoSerializer(true));
config.getSerializationConfig().addSerializerConfig(productSerializer);
hz=Hazelcast.newHazelcastInstance(config);
mapItemCount=hz.getMap("objectMap");
MyDataObject obj = new MyDataObject();
ISet<Integer> iset = hz.getSet("zlibset2");
iset.add(1);
obj.setMyList(iset);
mapItemCount.put("1", obj);
System.out.println(mapItemCount.get("1").getMyList().toString());
}
}
The below code is for productKyroSerializer:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterInputStream;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;
public class ProductKryoSerializer implements StreamSerializer {
private final boolean compress;
private static final ThreadLocal<Kryo> kryoThreadLocal
= new ThreadLocal<Kryo>() {
#Override
protected Kryo initialValue() {
Kryo kryo = new Kryo();
kryo.register(MyDataObject.class);
return kryo;
}
};
public ProductKryoSerializer(boolean compress) {
this.compress = compress;
}
public int getTypeId() {
return 2;
}
public void write(ObjectDataOutput objectDataOutput, MyDataObject product)
throws IOException {
Kryo kryo = kryoThreadLocal.get();
if (compress) {
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(16384);
DeflaterOutputStream deflaterOutputStream =
new DeflaterOutputStream(byteArrayOutputStream);
Output output = new Output(deflaterOutputStream);
kryo.writeObject(output, product);
output.close();
byte[] bytes = byteArrayOutputStream.toByteArray();
objectDataOutput.write(bytes);
} else {
Output output = new Output((OutputStream) objectDataOutput);
kryo.writeObject(output, product);
output.flush();
}
}
public MyDataObject read(ObjectDataInput objectDataInput)
throws IOException {
InputStream in = (InputStream) objectDataInput;
if (compress) {
in = new InflaterInputStream(in);
}
Input input = new Input(in);
Kryo kryo = kryoThreadLocal.get();
return kryo.readObject(input, MyDataObject.class);
}
public void destroy() {
}
// #Override
// public Object read(ObjectDataInput arg0) throws IOException {
// // TODO Auto-generated method stub
// return null;
// }
public void write(ObjectDataOutput arg0, Object arg1) throws IOException {
// TODO Auto-generated method stub
}
}
And moreover, I think there should be some proper method to retrieve the object after deserialisation.
You can see the "objectMap" hazelcast's IMap instance and I have updated some code in hazelcast.xml:
<map name="objectMap">
<in-memory-format>OBJECT</in-memory-format>
</map>
<map name="cachedMap">
<in-memory-format>CACHED</in-memory-format>
</map>
<map name="binaryMap">
<in-memory-format>BINARY</in-memory-format>
</map>
and the code for myDataObject is
import com.hazelcast.core.IList;
import com.hazelcast.core.ISet;
public class MyDataObject {
ISet<Integer> myList;
public ISet<Integer> getMyList() {
return myList;
}
public void setMyList(ISet<Integer> myList) {
this.myList = myList;
}
}
ISet is not serializable and cannot be serialized directly as a field inside of a class. See the following snippet for a possible solution.
public class MyDataObject
implements KryoSerializable, HazelcastInstanceAware {
private ISet<Integer> myList;
private String myListName;
public ISet<Integer> getMyList() {
return myList;
}
public void setMyList(ISet<Integer> myList) {
this.myList = myList;
this.myListName = myList.getName();
}
public void write (Kryo kryo, Output output) {
output.writeString(myListName);
}
public void read (Kryo kryo, Input input) {
this.myListName = input.readString();
}
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.myList = hazelcastInstance.getSet(myListName);
}
}
I guess that should work (at least kind of ;-)) just wrote it in the browser.
I have read many of Blaise Doughan's StackOverflow answers and blog posts, and I thought I understood his examples for using #XmlAnyElement with Object[]'s.
But the same principles doesn't appear to work with List - as shown with the example below (partly copied from one of his examples, and partly copied from xjc output).
I believe the code below should create JSON:
{"method":"test","status":["value":"500"]}
but instead it is creating the JASON:
{"method":"test","value":["com.mdsh.test.JsonRequestTest$Status#64dbfe37"]}
which is not much use to me.
Can anyone guide me to marshall this small object correctly, please?
package com.mdsh.test;
import static org.junit.Assert.assertEquals;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.junit.Test;
import org.jvnet.jaxb2_commons.lang.JAXBToStringStrategy;
import org.jvnet.jaxb2_commons.lang.ToStringStrategy;
import org.jvnet.jaxb2_commons.locator.ObjectLocator;
public class JsonRequestTest
{
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public static class Request
{
String method;
#XmlAnyElement(lax = true)
protected List<Object> any = new Vector<Object>();
public String getMethod()
{
return this.method;
}
public void setMethod(final String value)
{
this.method = value;
}
public List<Object> getAny()
{
if (this.any == null) {
this.any = new Vector<Object>();
}
return this.any;
}
#Override
public String toString()
{
final ToStringStrategy strategy = JAXBToStringStrategy.INSTANCE;
final StringBuilder buffer = new StringBuilder();
append(null, buffer, strategy);
return buffer.toString();
}
public StringBuilder append(final ObjectLocator locator, final StringBuilder buffer, final ToStringStrategy strategy)
{
strategy.appendStart(locator, this, buffer);
appendFields(locator, buffer, strategy);
strategy.appendEnd(locator, this, buffer);
return buffer;
}
public StringBuilder appendFields(final ObjectLocator locator, final StringBuilder buffer, final ToStringStrategy strategy)
{
{
List<Object> theAny;
theAny = (((this.any!= null)&&(!this.any.isEmpty()))?getAny():null);
strategy.appendField(locator, this, "any", buffer, theAny);
}
return buffer;
}
}
public static class Status
{
int value;
public int getValue()
{
return this.value;
}
public void setValue(final int value)
{
this.value = value;
}
}
#Test
public void testListOfObjects() throws JAXBException
{
System.setProperty(JAXBContext.class.getName(), "org.eclipse.persistence.jaxb.JAXBContextFactory");
final Map<String, Object> props = new HashMap<String, Object>();
props.put(MarshallerProperties.MEDIA_TYPE, "application/json");
props.put(MarshallerProperties.JSON_INCLUDE_ROOT, false);
final JAXBContext ctx = JAXBContext.newInstance(
new Class<?>[] { Request.class },
props);
final Marshaller m = ctx.createMarshaller();
final StringWriter writer = new StringWriter();
final Request req = new Request();
req.setMethod("test");
final Status stat = new Status();
stat.setValue(500);
req.getAny().add(stat);
m.marshal(req, writer);
assertEquals("{\"method\":\"test\",\"status\":[\"value\":\"500\"]}",
writer.toString());
}
}
I found this code on stackoverflow that explain how to get all running process
on windows, this get name and pid
Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.UNICODE_OPTIONS);
Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();
WinNT.HANDLE snapshot = kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
try {
while (kernel32.Process32Next(snapshot, processEntry)) {
System.out.println(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile));
}
} finally {
kernel32.CloseHandle(snapshot);
}
My question is: how can i get the process path?
Using JNA, you need to define the MODULEENTRY32 structure and map some required functions :
import java.util.Arrays;
import java.util.List;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.win32.W32APIOptions;
public interface ProcessPathKernel32 extends Kernel32 {
class MODULEENTRY32 extends Structure {
public static class ByReference extends MODULEENTRY32 implements Structure.ByReference {
public ByReference() {
}
public ByReference(Pointer memory) {
super(memory);
}
}
public MODULEENTRY32() {
dwSize = new WinDef.DWORD(size());
}
public MODULEENTRY32(Pointer memory) {
super(memory);
read();
}
public DWORD dwSize;
public DWORD th32ModuleID;
public DWORD th32ProcessID;
public DWORD GlblcntUsage;
public DWORD ProccntUsage;
public Pointer modBaseAddr;
public DWORD modBaseSize;
public HMODULE hModule;
public char[] szModule = new char[255+1]; // MAX_MODULE_NAME32
public char[] szExePath = new char[MAX_PATH];
public String szModule() { return Native.toString(this.szModule); }
public String szExePath() { return Native.toString(this.szExePath); }
#Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[] {
"dwSize", "th32ModuleID", "th32ProcessID", "GlblcntUsage", "ProccntUsage", "modBaseAddr", "modBaseSize", "hModule", "szModule", "szExePath"
});
}
}
ProcessPathKernel32 INSTANCE = (ProcessPathKernel32)Native.loadLibrary(ProcessPathKernel32.class, W32APIOptions.UNICODE_OPTIONS);
boolean Module32First(HANDLE hSnapshot, MODULEENTRY32.ByReference lpme);
boolean Module32Next(HANDLE hSnapshot, MODULEENTRY32.ByReference lpme);
}
then you retrieve the processes and for each PID, retrieve the Module information (the path of the module is now available). If running from a 32bits process then you only get the Module information from 32bits processes (the path will be blank for the 64bits processes).
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.Tlhelp32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.win32.W32APIOptions;
public class ProcessPathAll {
public static void main(String ... args) {
Kernel32 kernel32 = (Kernel32) Native.loadLibrary(Kernel32.class, W32APIOptions.DEFAULT_OPTIONS);
Tlhelp32.PROCESSENTRY32.ByReference processEntry = new Tlhelp32.PROCESSENTRY32.ByReference();
WinNT.HANDLE processSnapshot =
kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPPROCESS, new WinDef.DWORD(0));
try {
while (kernel32.Process32Next(processSnapshot, processEntry)) {
// looks for a specific process
// if (Native.toString(processEntry.szExeFile).equalsIgnoreCase("textpad.exe")) {
System.out.print(processEntry.th32ProcessID + "\t" + Native.toString(processEntry.szExeFile) + "\t");
WinNT.HANDLE moduleSnapshot =
kernel32.CreateToolhelp32Snapshot(Tlhelp32.TH32CS_SNAPMODULE, processEntry.th32ProcessID);
try {
ProcessPathKernel32.MODULEENTRY32.ByReference me = new ProcessPathKernel32.MODULEENTRY32.ByReference();
ProcessPathKernel32.INSTANCE.Module32First(moduleSnapshot, me);
System.out.print(": " + me.szExePath() );
System.out.println();
}
finally {
kernel32.CloseHandle(moduleSnapshot);
}
// }
}
}
finally {
kernel32.CloseHandle(processSnapshot);
}
}
}