Sau rất nhiều thử nghiệm, tôi đã tìm thấy một giải pháp mà tôi thích bây giờ. Về cơ bản, nó hoạt động như sau: 1. Lấy ID tiến trình của quy trình mà bạn đã bắt đầu 2. Chuyển PID này sang phiên bản được sửa đổi của SendSignal.exe, sẽ gửi Ctrl-C thay vì Ctrl-Break
Cả hai bước không hoàn toàn thẳng về phía trước, nhưng gần như. Đối với 1. bạn cần lấy PID. Java không cung cấp bất kỳ cách nào để có được nó. Có một số chủ đề thảo luận về cách làm tốt nhất. Tôi quyết định cho một nơi bạn cần đến bây giờ tên (xem getProcessIDs() trong đoạn mã dưới đây).
Đối với 2. bạn cần có công cụ gửi CTRL-C đến một PID nhất định. Một lần nữa, Java không làm điều này. Có nhiều cách khác nhau để thực hiện điều đó (ví dụ: sử dụng trình bao bọc trong python hoặc như vậy), nhưng tất cả chúng đều hơi phức tạp. Tôi thấy dễ nhất là sử dụng .exe-File để thực hiện công việc. Đối với điều này, tôi sửa đổi SendSingal.exe. Bạn có thể lấy mã nguồn ở đây: 1. Sau đó, chỉ cần thay thế tất cả các lần xuất hiện của "BREAK" (cũng bằng chữ thường) bằng "C" và biên dịch lại.
Đổi tên exe thành SendSignalC.exe và đặt nó vào thư mục con ext \ của nơi bạn bắt đầu Java. Sau đó, hãy chạy mã bên dưới và gọi điện một cách vui vẻ, ví dụ: SendCTRLC.sendCtrlC ("tuyyourprogramiscall.exe").
/**
* Sends CTRL-C to running processes from Java (in Windows)
* and ca get ProcessID(s) for a given process name.
* IMPORTANT!
* This function NEEDS SendSignalC.exe in the ext\ subdirectory.
* @author Kai Goergen
*/
import java.io.*;
import java.util.*;
public class SendCTRLC() {
/**
* Get all PIDs for a given name and send CTRL-C to all
* @param processName
* @return
*/
public static List<String> sendCTRLC(String processName) {
// get all ProcessIDs for the processName
List<String> processIDs = getProcessIDs(processName);
System.out.println("" + processIDs.size() + " PIDs found for " + processName + ": " + processIDs.toString());
for (String pid : processIDs) {
// close it
sendCTRLC(Integer.parseInt(pid));
}
return processIDs;
}
/**
* Send CTRL-C to the process using a given PID
* @param processID
*/
public static void sendCTRLC(int processID) {
System.out.println(" Sending CTRL+C to PID " + processID);
try {
Process p = Runtime.getRuntime().exec("cmd /c ext\\SendSignalC.exe " + processID);
StreamGobbler.StreamGobblerLOGProcess(p);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Get List of PIDs for a given process name
* @param processName
* @return
*/
public static List<String> getProcessIDs(String processName) {
List<String> processIDs = new ArrayList<String>();
try {
String line;
Process p = Runtime.getRuntime().exec("tasklist /v /fo csv");
BufferedReader input = new BufferedReader
(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
if (!line.trim().equals("")) {
// Pid is after the 1st ", thus it's argument 3 after splitting
String currentProcessName = line.split("\"")[1];
// Pid is after the 3rd ", thus it's argument 3 after splitting
String currentPID = line.split("\"")[3];
if (currentProcessName.equalsIgnoreCase(processName)) {
processIDs.add(currentPID);
}
}
}
input.close();
}
catch (Exception err) {
err.printStackTrace();
}
return processIDs;
}
}
PS: Tôi rất muốn đính kèm SendSignalC.exe tại đây, nhưng tôi không nghĩ rằng mình được phép. Nhưng dù sao, những thay đổi rất đơn giản và thẳng về phía trước nếu bạn có một chạy cpp-trình biên dịch ...
Cuối cùng, bạn đang cố gắng đạt được điều gì? –
Thực hiện trình bao bọc xung quanh DOS/windows3 cũ.1/win95 ứng dụng – Nettogrof
nó sẽ làm việc nhưng bạn nên gửi phá vỡ chỉ một lần, làm điều đó hai lần rõ ràng là sẽ giết chết quá trình chính. –