# Prozess der von anderem Prozess gestartet wurde beenden? (Windows Bildschirmtastatur)



## Soahc (8. Jun 2011)

Hallo,

ich habe mir eine kleine Methode geschrieben, die mir unter Windows die Bildschirmtastatur starten soll. Ist der Prozess schon gestartet, soll der Prozess beendet werden.


```
private Process systemKeyBoardProzess;
	private void showSystemKeyBoard(){
		try {
			if(systemKeyBoardProzess!=null){
				try{
					systemKeyBoardProzess.exitValue();
				}catch(IllegalThreadStateException e){
					System.out.println("beenden");
					systemKeyBoardProzess.destroy();
					systemKeyBoardProzess = null;
					return;
				}
			}
			
			String sysroot = System.getenv("SystemRoot");
			ProcessBuilder builder = new ProcessBuilder(new String[] {"cmd.exe", "/C", sysroot + "//system32//osk.exe"});
			systemKeyBoardProzess = builder.start();
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
```

Da ich gerade unter Windows 7 entwickle und sich die exe der Bildschirmtastatur im per UAC geschützten Verzeichniss "Windows\system32" befindet, kann ich sie nur über den Umweg der Commandline (cmd.exe) starten.:


```
ProcessBuilder builder = new ProcessBuilder(new String[] {"cmd.exe", "/C", sysroot + "//system32//osk.exe"});
systemKeyBoardProzess = builder.start();
```

Wie ich der API-Doku entnehme, kann ich mit 


```
systemKeyBoardProzess.destroy();
```

den Prozess wieder beenden, nur handelt es sich dabei leider um den Commandline-Prozess und nicht den vom ihm aus gestarteten Bildschirmtastatur-Prozess. Ich habs jetzt schon mit "taskkill /im osk.exe" über den Commandline-Prozess probiert, aber da fehlen dann wieder die Rechte.

Hat vielleicht schon jemand ein Problem dieser Art lösen können?

vielen Dank,

Soahc


----------



## Andi_CH (8. Jun 2011)

Beenden geht am Besten über Interprozesskommunikation (ich weiss nicht ob das in deinem Fall möglich ist, aber ich glaube nicht) schicke dem anderen Prozess eine Meldung "Bitte beende dich" (bitte nicht wörtlich nehmen, es muss kein String sein) worauf der das dann auch tut.

Aber so wie ich dich verstehe, ist das andere etwas, was nicht du geschrieben hast?

Jede andere Lösung ist Betriebssystemabhängig - was in deinem Fall ja zu reichen scheint


----------



## Soahc (8. Jun 2011)

Das Problem ist, dass ich ja keine direkte verbindung zu dem osk-prozess habe. Daher kann ich ihm auch nicht so ohne weiteres Mitteilen, dass er beendet werden soll. Nach ein wenig rumgebastel habe ich nun doch noch eine Lösung gefunden -> mit tskill. Ist sicher nicht die eleganteste und funktioniert natürlich nur unter Windows, aber sie funktioniert schon mal:


```
private Process systemKeyBoardProzess;
	
    private void showSystemKeyBoard() throws IOException, InterruptedException {
		if(System.getProperty("os.name").toLowerCase().indexOf("windows")==-1){
			return;
		}
		if (systemKeyBoardProzess != null) {
			try {
				systemKeyBoardProzess.exitValue();
			} catch (IllegalThreadStateException e) {
				System.out.println("beenden");
				Process closeProcess = new ProcessBuilder(new String[] {"cmd.exe", "/C", "tskill osk" }).start();
				closeProcess.waitFor();
				closeProcess.destroy();
				systemKeyBoardProzess.destroy();
				systemKeyBoardProzess = null;
				return;
			}
		}

		ProcessBuilder builder = new ProcessBuilder(new String[] { "cmd.exe","/C", "osk.exe" });
		systemKeyBoardProzess = builder.start();
	}
```

gruß, Soahc


----------



## Andi_CH (8. Jun 2011)

unter Linux ist es "kill -9 name" 

Wenn nur der String[] BS-abhängig ist, ist es defintiv kein Problem - der könnte ja aus einer Umgebungsvariablen, Systemporpertie, einer config Datei oder sonstwoher gelesen werden ....


----------



## muckelzwerg (8. Jun 2011)

Ist doch alles in Ordnung. tskill bzw. taskkill ist doch extra dafür gemacht.
Microsoft Corporation
Du kannst sowieso nichts anderes machen, als das was in taskkill passiert.
WM_CLOSE an alle Fenster, warten und hoffen, dann wieder TerminateProcess() wenn der Prozess nicht aufgibt, das dann von java aus ...
und alles nur um die Funktionalität zu bekommen, die vom BS mitgeliefert wird.
TerminateProcess Function (Windows)

Oder brauchst Du es für ein Windows wo es kein passendes Tool gibt?
Dann findest Du im Netz genug Anleitungen, wie Du das WM_CLOSE aus z.B. C++ senden kannst. Dann musst Du den "taskkill" leider selbst bauen.
(c++ - using sendmessage to send wm_close to another process - Stack Overflow
How To Terminate an Application "Cleanly" in Win32
Processes: How can I kill a process? - CodeGuru Forums
...)


----------

