如何通过双击图标来执行JAVA程序?
Posted
技术标签:
【中文标题】如何通过双击图标来执行JAVA程序?【英文标题】:How to execute JAVA program by double clicking on icon? 【发布时间】:2014-04-15 19:29:52 【问题描述】:我写了一个java程序。现在我想在没有 IDE、Eclipse 等的情况下打开我的控制台 Java 应用程序,但只需双击我桌面上的可执行版本即可。
我已将 java 项目导出到 Runnable .JAR 文件中,但无法打开。当我尝试使用 cmd 打开应用程序时。 java -jar ApplicatonName.jar 一切都很好。但是这个过程太复杂了,不方便用户使用。
那么有没有办法用 JAVA 做这样的事情呢?
提前致谢:)
【问题讨论】:
也许看看Launch4j 这将归结为操作系统与*.jar
的关联 - 另一个问题是,通常双击图标与基于 GUI 的应用程序相关联,而不是基于控制台的应用程序,那么为什么要双击图标可能看起来什么都不做,应用程序已经启动,但它没有任何显示...
【参考方案1】:
根据操作系统创建一个bat
或sh
文件,并将java -jar ApplicationName.jar
放入该文件中。
您可以双击该文件来启动您的应用程序。
Windows 示例:
创建一个文件MyProgram.bat
。在文本编辑器中打开文件。添加java -jar MyApplicationName.jar
(将 MyApplicationName 替换为您的应用程序的名称/jar 的名称)。保存文件。双击创建的文件打开你的程序。
【讨论】:
【参考方案2】:今天早上我遇到了同样的问题,搜索了一下,并根据可用知识创建了一个静态类。它解决了 Windows 的问题,但其他系统的用户应该能够轻松添加必要的内容 - 我只是不知道正确的系统命令(如果有的话)。我留下了 printEnvironmentInfo() 方法以寻求帮助。
它的作用:
它允许双击启动标准 Java 控制台应用程序,而无需更改操作系统或创建文件。程序是这样的:
如果您在 IDE 中,它只会返回。
它只是在你有控制台的情况下返回。
它在新控制台中启动当前运行的 .jar 文件并退出。
使用方法:
创建 Java 控制台应用程序。
创建类文件 AutoRunFromConsole 并将以下代码粘贴到 package 语句下,替换所有内容。
作为主方法中的第一条语句之一,执行 AutoRunFromConsole.runYourselfInConsole(true); (如果您希望在应用程序结束后关闭控制台,则为 false)。
工作原理:
确定正在运行的 Java 应用程序的 .jar 文件名,并检查该文件是否真的存在于当前目录中,以及它是否真的是一个文件。
如果这不起作用,我们必须在 IDE 中,因此有一个控制台。这应该是可靠的,但还有另一种方法:对(重载)方法的不同调用允许您交出 main 方法的命令行参数。如果第一个参数是“ide”(忽略大小写。),该方法只返回。当使用此其他调用时,如果无法确定可执行文件名称(您甚至可以为其提供回退。),则会显示一条消息(见下文)。
检查 System.console() 是否返回 null。如果没有,它只是返回。
根据操作系统确定一个命令行字符串(目前仅适用于 WINDOWS,但您只需要填写空白),然后使用 Runtime.getRuntime().exec(); 执行它。如果操作系统尚不支持,则会显示一个消息窗口,说明该程序需要从控制台运行,包括。语法。
如果您有改进(尤其是其他系统的命令行字符串),请告诉我。
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.security.CodeSource;
import java.util.Map;
import java.util.Properties;
/**
* Created by Reddit user king_of_the_universe / *** user Dreamspace President / dreamspace-president.com
* <p>
* v[(2), 2015-11-13 13:00 UTC]
* <p>
* One static method call will start a new instance of *THIS* application in the console and will EXIT the current
* instance. SO FAR ONLY WORKS ON WINDOWS! Users of other systems need to assist here. The methods are all in place.
*/
final public class AutoRunFromConsole
final private static String FAILMESSAGE_TITLE = "Please run in console.";
final private static String FAILMESSAGE_BODY = "This application must be run in the console (or \"command box\").\n\nIn there, you have to type:\n\njava -jar nameofprogram.jar";
private static void showFailMessageAndExit()
JOptionPane.showMessageDialog(null, FAILMESSAGE_BODY, FAILMESSAGE_TITLE, JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
private enum OSType
UNDETERMINED, WINDOWS, LINUX, MACOS
private static OSType getOsType()
// final String osName = System.getProperty("os.name");
// final String osVersion = System.getProperty("os.version");
// final String osArchitecture = System.getProperty("os.arch");
// System.out.println("\n\nOSNAME: " + osName);
// System.out.println("\n\nOSVERSION: " + osVersion);
// System.out.println("\n\nOSARCHITECTURE: " + osArchitecture);
final String osName = System.getProperty("os.name", "").toLowerCase();
if (osName.startsWith("windows"))
return OSType.WINDOWS;
else if (osName.startsWith("linux"))
return OSType.LINUX;
else if (osName.startsWith("mac os") || osName.startsWith("macos") || osName.startsWith("darwin"))
return OSType.MACOS;
return OSType.UNDETERMINED;
/**
* Checks if the program is currently running in console, and if not, starts the program from console and EXITS this
* instance of the program. Should be (one of) the first calls in your program.
* <p>
* This is the less safe variant of the method: To check if you're currently in the IDE, it just tries to find the
* executable name and if it exists in the current path. This should word perfectly at all times in IntelliJ - I
* don't know what values getExecutableName() returns inside Eclipse, but I suspect it will work just as well.
* <p>
* It's also less safe because you can't give a fallback executable name, but I believe it should do the trick in
* all situations.
* <p>
* If this is used on a system other than Windows, a message box is shown telling the user to start the program from
* the console. BECAUSE I DON'T KNOW HOW TO OPEN A CONSOLE ON OTHER SYSTEMS. SEE startExecutableInConsole();
*/
public static void runYourselfInConsole(final boolean stayOpenAfterEnd)
runYourselfInConsole(false, stayOpenAfterEnd, null, null);
/**
* Checks if the program is currently running in console, and if not, starts the program from console and EXITS this
* instance of the program. Should be (one of) the first calls in your program.
* <p>
* This is the safer variant of the method: The first command line argument GIVEN BY THE IDE'S RUN CONFIGURATION
* should be "ide" (Case is ignored.), which this method will use to determine if it's running from the IDE.
* <p>
* It is also safer because you can give a fallback executable name in case getExecutableName() could not determine
* it.
* <p>
* Ultimately, it is safer because if the executable could not be determined, it shows a message box telling the
* user to start the program from the console.
* <p>
* You will probably never make use of this variant. It's meant to be a solution if all else seems to fail (e.g.
* customer calls and you need a quick fix).
* <p>
* If this is used on a system other than Windows, a message box is shown telling the user to start the program from
* the console. BECAUSE I DON'T KNOW HOW TO OPEN A CONSOLE ON OTHER SYSTEMS. SEE startExecutableInConsole();
*
* @param psvmArguments The arguments given to the main method.
* @param fallbackExecutableName Can be null. In case getExecutableName() can't determine the proper name, the
* fallback is used.
*/
public static void runYourselfInConsole(final String[] psvmArguments, final String fallbackExecutableName, final boolean stayOpenAfterEnd)
runYourselfInConsole(true, stayOpenAfterEnd, psvmArguments, fallbackExecutableName);
/**
* see the other two methods
*/
private static void runYourselfInConsole(final boolean useSaferApproach, final boolean stayOpenAfterEnd, final String[] psvmArguments, final String fallbackExecutableName)
String executableName = getExecutableName(fallbackExecutableName);
if (useSaferApproach)
if (isRunFromIDE(psvmArguments))
return;
else
if (executableName == null)
// Running from IDE.
return;
if (isRunningInConsole())
return;
if (executableName == null)
showFailMessageAndExit();
startExecutableInConsole(executableName, stayOpenAfterEnd);
System.exit(0);
/**
* Opens a console window and starts the Java executable there.
* <p>
* If this is used on a system other than Windows, a message box is shown telling the user to start the program from
* the console. BECAUSE I DON'T KNOW HOW TO OPEN A CONSOLE ON OTHER SYSTEMS.
*
* @param executableName the full file name of the executable (without path)
* @param stayOpenAfterEnd If true (and if someone can figure out the necessary parameters for other systems than
* Windows), the console will not close once the executable has terminated. This is useful
* e.g. if you want to give some kind of bye bye message because you actually assumed that
* people start the program from console manually.
*/
private static void startExecutableInConsole(final String executableName, final boolean stayOpenAfterEnd)
String launchString = null;
switch (getOsType())
case UNDETERMINED:
break;
case WINDOWS:
if (stayOpenAfterEnd)
launchString = "cmd /c start cmd /k java -jar \"" + executableName+"\""; // No, using /k directly here DOES NOT do the trick.
else
launchString = "cmd /c start java -jar \"" + executableName+"\"";
break;
case LINUX:
break;
case MACOS:
// launchString="/usr/bin/open -a Terminal /path/to/the/executable";
break;
if (launchString == null)
showFailMessageAndExit();
try
Runtime.getRuntime().exec(launchString);
catch (IOException e)
e.printStackTrace();
/**
* @param args the args as given to PSVM
* @return whether the first command line argument was "ide" (ignoring case). Don't forget to change your IDE's run
* configuration accordingly.
*/
private static boolean isRunFromIDE(final String[] args)
return args != null && args.length > 0 && args[0].equalsIgnoreCase("ide");
/**
* @return if System.console() is available. DOES NOT WORK properly from IDE, will return false then even though it
* should be true. Use isRunFromIDE or other means additionally.
*/
private static boolean isRunningInConsole()
return System.console() != null;
/**
* @param fallbackExecutableName Can be null. In the very unlikely case this method can't determine the executable,
* the fallback will also be checked. But if the fallback also doesn't exist AS A FILE
* in the CURRENT path, null will be returned regardless, even if you're sure that
* your fallback should be correct.
* @return the name of the running jar file, OR NULL if it could not be determined (which should be a certainty
* while in IDE, hence can be abused for determining that).
*/
public static String getExecutableName(final String fallbackExecutableName)
// APPROACH 1 - THE ONE EVERYBODY ON *** IS REPEATING
String executableNameFromClass = null;
final CodeSource codeSource = AutoRunFromConsole.class.getProtectionDomain().getCodeSource();
if (codeSource == null)
System.err.println("UNEXPECTED: Main.class.getProtectionDomain().getCodeSource() returned null");
else
final String path = codeSource.getLocation().getPath();
if (path == null || path.isEmpty())
System.err.println("UNEXPECTED: codeSource.getLocation().getPath() returned null or empty");
else
executableNameFromClass = new File(path).getName();
// APPROACH 2 - QUERY SYSTEM PROPERTIES
final Properties properties = System.getProperties();
final String executableNameFromJavaClassPathProperty = properties.getProperty("java.class.path");
final String executableNameFromSunJavaCommandProperty = properties.getProperty("sun.java.command");
// System.out.println("\n\nexecutableNameFromClass:\n" + executableNameFromClass);
// System.out.println("\n\nexecutableNameFromJavaClassPathProperty:\n" + executableNameFromJavaClassPathProperty);
// System.out.println("\n\nexecutableNameFromSunJavaCommandProperty:\n" + executableNameFromSunJavaCommandProperty);
// System.out.println("\n\nfallbackExecutableName:\n" + fallbackExecutableName);
if (isThisProbablyTheExecutable(executableNameFromClass))
return executableNameFromClass;
if (isThisProbablyTheExecutable(executableNameFromJavaClassPathProperty))
return executableNameFromJavaClassPathProperty;
if (isThisProbablyTheExecutable(executableNameFromSunJavaCommandProperty))
return executableNameFromSunJavaCommandProperty;
if (isThisProbablyTheExecutable(fallbackExecutableName))
return fallbackExecutableName;
return null;
/**
* @param candidateName suspected name of the running java executable
* @return if name is not null, ends with ".jar" (Case is ignored.), and points to a FILE existing in the CURRENT
* directory.
*/
private static boolean isThisProbablyTheExecutable(final String candidateName)
if (candidateName == null || !candidateName.toLowerCase().endsWith(".jar"))
return false;
final File file = new File(candidateName);
return file.exists() && file.isFile();
public static void main(final String[] args)
AutoRunFromConsole.runYourselfInConsole(true);
printEnvironmentInfo();
/**
* for debugging purposes
*/
public static void printEnvironmentInfo()
System.out.println("\n\n\n\n-------------------------- System.getProperties() --------------------------");
final Properties properties = System.getProperties();
for (final Map.Entry<Object, Object> entry : properties.entrySet())
System.out.println(entry);
System.out.println("\n\n\n\n----------------------------- System.getenv() ------------------------------");
final Map<String, String> env = System.getenv();
for (final Map.Entry<String, String> entry : env.entrySet())
System.out.println(entry);
System.out.print("\n\n\n\n");
【讨论】:
不错!但是,我注意到一个错误:如果通过双击运行它,则无法在 CMD 窗口中突出显示文本。 @androidDev 一定是你的问题,对我有用(刚刚测试过)。我也不知道如何更改 CMD 窗口的功能(更不用说通过 Java)了。【参考方案3】:我知道这个答案已经很晚了。但它可能对现在看到这个问题的人有所帮助。
首先右键单击文件并选择打开方式...
然后选择始终使用此程序打开 jar 文件。
然后点击选择另一个应用程序(或类似的东西)。
然后浏览到你的java安装目录\bin。(C:\Program files\Java\jdk-17\bin)
然后选择jar.exe
【讨论】:
以上是关于如何通过双击图标来执行JAVA程序?的主要内容,如果未能解决你的问题,请参考以下文章
在 Mac OS X 中双击文档文件以打开 Java 应用程序
如果通过双击 JNLP 文件启动 JAVA Web Start 应用程序,如何允许它访问 macOS Catalina 上的文件系统?