我编写了一个JavaFX程序,该程序运行一个使用google控制台搜索api来获取数据的python脚本。在将其部署为独立程序(.exe)之前,它工作正常。安装程序后,它会运行良好,直到单击运行脚本的按钮为止。它什么也没做。
单击按钮后,它会成功检查是否已安装python,然后在尝试运行脚本时出现问题。我已经指定了这样的路径“ ./src/com/fortunamaritime/”,我认为这可能是问题所在。
private static final String ANALYTICS_PATH ="./src/com/fortunamaritime/";
方法内
//set up the command and parameter
String[] cmd = new String[3];
cmd[0] = "python";
cmd[1] = "analytics.py";
cmd[2] = "https://fortunamaritime.com.tr";
String command = cmd[0] + " " + cmd[1] + " " + cmd[2] + " " +
startDate + " " + endDate;
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "cd " + new
File(ANALYTICS_PATH).getAbsolutePath() + " && " + command);
builder.redirectErrorStream(true);
Process p = builder.start();
我已将控制台输出重定向到.txt文件,以查看发生了什么,只有一行显示“系统找不到指定的路径”。
我已经从绝对路径切换到相对路径,并且产生了此错误: 文件名,目录名称或卷标签语法不正确。 我还将此行打印到控制台
this.getClass().getResource("/com/fortunamaritime/analytics.py")
结果是:
jar:file:/ D:/IdeaProjects/FortunaWebTracker/out/artifacts/FortunaWebTracker/FortunaWebTracker.jar!/com/fortunamaritime/analytics.py
是否可以访问jar文件的内部并通过cmd通过剥离此URL的一部分从那里运行脚本?
答案 0 :(得分:1)
将脚本复制到一个(可能是临时的)文件中,然后从该文件中运行它。
您可以使用Main.class.getResourceAsStream(String resc)
(相对于main)或Main.class.getClassLoader().getResourceAsStream(String resc)
(相对于root)以InputStream形式获取脚本
您可以使用java.nio.file.Files#createTempFile(String,String
并在退出时删除该文件。
您还可以将脚本复制到用户主目录或相对于exe的用户中(并且不要将其删除)。
例如,您可以执行以下操作:
File dir=new File("./resc");
if(!dir.exists()) {
dir.mkdirs();
}
File analyticsFile=new File(dir,"analytics.py");
if(!analyticsFile.exists()) {
/*
* alternative:
* this.getClass().getResourceAsStream("com/fortunamaritime/analytics.py")
*/
try(InputStream analyticsIn = this.getClass().getClassLoader().getResourceAsStream("analytics.py")){
Files.copy(analyticsIn, analyticsFile.toPath());
}
}
/*
* alternative: String command=String.join(" ",new String[]{"python",analyticsFile.getAbsolutePath(),"https://fortunamaritime.com.tr"});
*/
String command="python "+analyticsFile.getAbsolutePath()+" https://fortunamaritime.com.tr";
/*
* alternative (without error redirection): Process p=Runtime.getRuntime().exec(command);
*/
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process p=builder.start();
答案 1 :(得分:0)
我已经解决了我的问题。 首先是代码示例,然后进行解释;
String path = new
File(Main.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getPath();
path=path.substring(0,path.length()-21);
// set up the command and parameter
String[] cmd = new String[3];
cmd[0] = "python";
cmd[1] = "analytics.py";
cmd[2] = "https://fortunamaritime.com.tr";
String command0="jar xf FortunaWebTracker.jar" +
"com/fortunamaritime/analytics.pycom/fortunamaritime/client_secrets.json" +
" com/fortunamaritime/webmasters.dat";
String command1 = cmd[0] + " " + cmd[1] + " " + cmd[2] + " " + startDate + " " +
endDate;
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", "cd " + path + " && " +
command0+"&&"+"cd "+path+"\\com\\fortunamaritime"+" && "+command1);
builder.redirectErrorStream(true);
Process p = builder.start();
我的第一个错误是使用绝对路径,当我通过以下方法获得所需的路径时,出现了第二个问题:
File(Main.class.getProtectionDomain().getCodeSource().getLocation()
.toURI()).getPath();
//Jar's name is 21 characters long, minus that and I get the directory path
path=path.substring(0,path.length()-21);
第二个问题是解压缩jar中的元素,因此我在cmd中使用了以下命令:
jar xf FortunaWebTracker.jar
com / fortunamaritime / analytics.py com / fortunamaritime / client_secrets.json com / fortunamaritime / webmasters.dat
然后我可以使用它。