背景:
开发中需要外接一个USB设备,然后在上位机通过grpc协议和下位机进行通行,USB设备插到上位机上以后会以一个RNDIS 网络设备存在,如果要想和它通信,需要先设置Rndis网络的地址,每次连接不同的设备后都需要收到设置这个地址,不利于运维人员维护,所以想通过JAVA代码来自动找到Rndis设备,然后在代码中运行CMD命令设置IP地址。
1、找到指定类型的网络适配器
public String getRndisName() {
String line = "";
String netWorkName = null;
boolean hasResult = false;
try {
Process ps = Runtime.getRuntime().exec("cmd /c ipconfig /all");
BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream(), "gbk"));
while (null != (line = br.readLine())) {
if (line == null || line.length() == 0) {
continue;
}
int spaceIndex = line.indexOf(" ");
int colonIndex = line.indexOf(":");
boolean isColonLast = colonIndex == line.length() - 1;
if (spaceIndex != -1 && isColonLast) {
String adapterStr = line.replace(":", "");
netWorkName = adapterStr.substring(spaceIndex + 1, adapterStr.length());
}
if (line.toLowerCase().contains("remote ndis")) {
hasResult = true;
break;
}
}
ps.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if (hasResult) {
return netWorkName;
} else {
return null;
}
}
2、判断网络是否联通
public boolean ping(String ipAddress) throws Exception {
int timeOut = 3000; //超时应该在3钞以上
boolean status = InetAddress.getByName(ipAddress).isReachable(timeOut);
// 当返回值是true时,说明host是可用的,false则不可。
//Runtime.getRuntime().exec("ping -c 1 "+ ip).waitFor()
return status;
}
3、设置指定网络适配器的地址
public interface IOnResultListener{
boolean onResult(boolean isOk);
}
public void setRndisIP(IOnResultListener listener) {
new Thread(){
public void run(){
try {
sleep(4000);
boolean isConnectOk = RNdisSetting.getInstance().ping("172.16.110.6");
if(!isConnectOk){
boolean isOk = RNdisSetting.getInstance().setRndisIp();
if(listener != null){
listener.onResult(isOk);
}
}else{
if(listener != null){
listener.onResult(isConnectOk);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 以管理员的权限执行网络设置
*/
public boolean setRndisIp() {
String rndisName = getRndisName();
boolean success = false;
try {
String command = "netsh interface ip set address name=\"" + rndisName + "\" source=static addr=172.16.110.103 mask=255.255.0.0";
logger.info("setRndisIp : " + command);
String verb = "runas";
ShellAPI.SHELLEXECUTEINFO exec = new ShellAPI.SHELLEXECUTEINFO();
exec.lpFile = "cmd.exe";
exec.lpParameters = "/c " + command;
exec.lpVerb = verb;
exec.nShow = WinUser.SW_SHOWDEFAULT;
success = Shell32.INSTANCE.ShellExecuteEx(exec);
if (!success) {
System.out.println("Failed to elevate privileges");
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
return success;
}