簡體   English   中英

如何從 Java 啟動和終止 .net dll?

[英]How to start and kill a .net dll from java?

我正在從事一個旨在將 opc ua 數據發布到 microsoft azure 的項目。 到目前為止,即使 opc ua 服務器斷開連接,opc 發布者似乎也發布數據。 它只是發布最后一個已知值。 這不是我們想要的。 該項目的另一部分是自動發現網絡中的新 opc ua 服務器。 為了實現這一點,我編寫了一個 java 程序,如果發現新的 opc ua 服務器,它會啟動一個 opc 發布者實例。 起初我只更新了一個發布者的publishednodes.json 但這似乎並不可靠。

OPC Publisher 是一個 .NET 應用程序,可以在 Visual Studio 2017 中構建為 dll。

問題是:如果 opc ua 服務器斷開連接,我的工具應該會終止發布者進程。 它確實殺死了 java 進程,但 opc 發布者不會停止。


我嘗試通過 processbuilder 運行發布者並使用 p.destroy() 銷毀進程,但沒有產生任何結果。 我還嘗試使用我創建的用於容納發布者的 jar 的 pid 來終止該進程。


這就是我啟動 opc 發布者的方式:

 ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "cd \\"publisher\\" && " + publisherString); pb.redirectErrorStream(true); Process p = pb.start();

(publisherString 類似於“dotnet opcpublisher.dll 選項”)

這真的很好用。

首先嘗試p.destroy();進程是p.destroy(); ......這根本不起作用。


第二次嘗試是讓主程序調用一個輔助 jar 來啟動發布者:

 ProcessBuilder publisher = new ProcessBuilder("cmd", "/c", "start", "java", "-jar", "StartPublisher.jar", options); publisher.redirectErrorStream(true); Process p = publisher.start();

然后我通過 JNA int pid = Kernel32.INSTANCE.GetCurrentProcessId();得到那個 jar 的int pid = Kernel32.INSTANCE.GetCurrentProcessId(); 並稍后使用 taskkill 作為第二個進程殺死它:

 ProcessBuilder terminator = new ProcessBuilder("cmd.exe", "/c", "taskkill /PID " + pid + " /T /F"); terminator.redirectErrorStream(true); Process t = terminator.start();

這確實會殺死 cmd 窗口和 java 進程,但如上所述,它不會殺死 dotnet 進程。


我完全不知道如何解決這個問題。 甚至有可能嗎? 或者我需要任何額外的庫嗎? 如果有人能幫助我,我會很高興。

嘗試這樣的事情,它要求您知道 dotnet 進程的可執行文件名稱。 但如果你這樣做,你可以殺死它! :)

public static void main(String args[]){
    ArrayList<String> pids = new ArrayList<String>();
    try {
        String EXECUTIBLE_TO_KILL = "MicrosoftEdge.exe";
        ProcessBuilder pb = new ProcessBuilder("tasklist.exe");
        Process p = pb.start();


        InputStream stdout = p.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
        while (br.ready() || p.isAlive()) {
            String line = br.readLine();
            String lineNormalized = line.replaceAll("\\s+", " "); //remove multiple whitespaces.
            String[] table = lineNormalized.split(" ");
            if(table[0].equals(EXECUTIBLE_TO_KILL)){
                pids.add(table[1]); //Get pid from tasklist and add it to list to kill.
            }
        }
    }catch(Exception e){

    }

    if(pids.size() > 0) { // If the executible is in the list. Kill it
        String cmd = "taskkill.exe /F";
        for (String pid : pids) {
            cmd = cmd + " /pid "+pid;
        }
        System.out.println(cmd);
        try{
            //Attempt to kill process.
            //ProcessBuilder will not work here.
            Runtime.getRuntime().exec(cmd).waitFor();
        }catch(Exception e){

        }
    }


}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM