1. .exe文件的生成
使用自己生成的应用程序,该应用程序带有参数。为了简便,以打印 输入的参数 为例,该应用程序的源码如下:
// myPrint.cpp #include < iostream > int main(int argc, char * argv[]){ char * it = argv[1]; if (it == nullptr){ std::cout << "This is nothing to be printed." << std::endl; }else{ while (*it != '\0'){ std::cout << *it++; } } char ch; std:: cin >> ch; // system("pause"); return 0; }
该函数经过编译连接后生成myPrint.exe应用程序。
2. java执行.exe, 为每个执行添加一个进程
*********************** 负责开启和关闭应用程序 ***********************
***维持一张String类,同开启的应用进程Process类的映射表
***1. 根据 序号 生成进程, 其他情况下也可以将String类转化为所需要的索引对象,只要与所运行的应用程序建立一一对应即可
***2. 根据 序号 , 查找当前的传输进程就可以关闭它
****2.1 关闭一个应用程序,由于只提供进程名,所以要先根据进程名获取pid,
****2.2 在根据pid KIll该应用
***3. 参考出处:
**** 3.1 2.1 和 2.2 参考 http://blog.sina.com.cn/s/blog_999cc24a0102vpjr.html
*****3.2 文中引入包的位置 https://java.net/projects/jna/downloads/directory/3.3.0
*****3.3 在3.1给出的地址下 下载两个jar包,在工程的src目录下新建lib文件夹,将jar文件放于里面,\src\lib
*********在eclispe选中当前工程,右键,build path--> config --> libraries 加入上面两个.jar即可
***************************************** --icesongqiang
import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT; class ProcManaSrc{ // 建立String与Proc的映射,根据数字做索引开关进程 private static Map m_String_Proc= new HashMap() ; private ProcManaSrc(){}; public static void startProcess(String str){ //先查询是否已经运行 String m_index = str; if(!m_String_Proc.containsKey(m_index)){ //不存在才创建 try { // String cmd = "cmd /c start .\\myprint\\myprint.exe" +"\"" + str +"\"" ; String cmd = ".\\myprint\\myprint.exe" +"\"" + str +"\"" ; // 要加上引号 System.out.print(cmd); System.out.println(); Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); m_String_Proc.put(str, proc); } catch (IOException e) { e.printStackTrace(); } } } public static void closeProcess(String str){ String m_index = str; if(m_String_Proc.containsKey(m_index)){ //存在才删除 killProcessTree(m_String_Proc.get(m_index)); m_String_Proc.remove(m_index); } }
private static void killProcessTree(Process process){ try { Field f = process.getClass().getDeclaredField("handle"); f.setAccessible(true); long handl = f.getLong(process); Kernel32 kernel = Kernel32.INSTANCE; WinNT.HANDLE handle = new WinNT.HANDLE(); handle.setPointer(Pointer.createConstant(handl)); int ret = kernel.GetProcessId(handle); Long PID = Long.valueOf(ret); String cmd = getKillProcessTreeCmd(PID); Runtime rt = Runtime.getRuntime(); Process killPrcess = rt.exec(cmd); killPrcess.waitFor(); killPrcess.destroy(); }catch(Exception e) { e.printStackTrace(); } }
private static String getKillProcessTreeCmd(Long Pid){ String result = ""; if(Pid != null) result = "cmd.exe /c taskkill /PID "+Pid+" /F /T "; return result; } } public class ProcMana{ ProcMana(){} public static void main(String agrv[]){ System.out.println("Start."); String strs[] = {"hello", "world", "bye"}; for(int i= 0 ; i< strs.length(); ++i){ ProcManaSrc.startProcess(strs[i]); } try { Thread.sleep(1000*30); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i= 0 ; i< strs.length(); ++i){ ProcManaSrc.closeProcess(strs[i]); } } }
可以看到,该代码为strs三个元素执行了.exe应用程序,而且根据元素不同进行开关控制。
值得注意的是,
// String cmd = "cmd /c start .\\myprint\\myprint.exe" +"\"" + str +"\"" ;
没有装cmd插件的话 要使用cmd /c start 才能看到打印输出,但是在程序管理里可以看到进程muprint.exe运行, 但是使用cmd /c start后是关闭不了的,个人感觉是因为使用后再开java程序应该找不到dos里开的应用程序。
这一点笔者也不太懂。但是一般的,我们都是直接调用其他应用程序,dos窗口是不怎么需要的,所以对很多情况都用适应性。笔者这里举该打印的应用程序只是做示范,实际上也是另有他用。