5

我有一个带有 main 方法的 java 类文件。在 Windows 中,我希望能够将文件拖到桌面图标/短/等上,这将调用将文件名提供给我的主要方法。基本上,我希望允许用户在程序执行时拖放文件,而不是在命令行上键入它们。

有什么想法吗?

4

5 回答 5

4

To build on daub815's answer, in Windows, you can use a batch file to pass arguments to another command. In this case, we'll use the java launcher to launch your class with the main method.

I did a quick Google search on how to do write a batch file to take multiple arguments, and found a page with a batch file to pass arguments to another command. Adapting from the example, here is what you can do:

@ECHO OFF
:Loop
IF "%1" == "" GOTO Done
java YourClass %1
SHIFT
GOTO Loop
:Done

Save the above file as a batch file (with a ".bat" extension), and then you can drag-and-drop files onto it, and it will be passed as arguments.

Also, you can call the batch file from the command line and pass arguments as well.

Edit: It appears that the batch file will not work with quoted arguments which contain spaces. Using a workaround presented in the site I've linked to will split the spaces contained in the quoted full path of the file into separate arguments, so that won't work either. If anyone has a good idea how to fix this, please either edit this entry, or post another answer. I will make this a community wiki.

于 2008-12-20T04:29:36.127 回答
3

如果您将类打包在一个可执行的 JAR 文件中(这就是您应该这样做的方式)并制作一个如下所示的 .reg 文件,那么 PhiLho 的答案非常有效。然后只需双击该 .reg 文件将其合并到注册表中即可。这使您既可以双击一个 JAR 文件来运行它,也可以通过拖放来启动它。

请记住更改安装 Java 可执行文件的路径。

Windows Registry Editor Version 5.00 

[HKEY_CLASSES_ROOT\.jar] 
@="jarfile" 

[HKEY_CLASSES_ROOT\jarfile\DefaultIcon] 
@="C:\\Java\\jdk1.7.0\\bin\\java.exe,1" 

[HKEY_CLASSES_ROOT\jarfile\shell\open] 
@="Run Java Program" 

[HKEY_CLASSES_ROOT\jarfile\shell\open\command] 
@="\"C:\\Java\\jdk1.7.0\\bin\\java.exe\" -jar \"%1\" %*" 

[HKEY_CLASSES_ROOT\jarfile\shellex\DropHandler] 
@="{86C86720-42A0-1069-A2E8-08002B30309D}" 
于 2012-07-02T10:11:51.527 回答
2

好的,我成功了……基础知识是在注册表中使用 DropHandler UUID。我做了一个基础设置,如下:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.class]
@="JavaClass"

[HKEY_CLASSES_ROOT\JavaClass\DefaultIcon]
@="C:\\Java\\jdk1.6.0_05\\bin\\java.exe,1"

[HKEY_CLASSES_ROOT\JavaClass\shell\open]
@="Run Java class"

[HKEY_CLASSES_ROOT\JavaClass\shell\open\command]
@="\"C:\\Java\\jdk1.6.0_05\\bin\\java.exe\" \"%1\" %*"

[HKEY_CLASSES_ROOT\JavaClass\shellex\DropHandler]
@="{86C86720-42A0-1069-A2E8-08002B30309D}"

并且......它没有工作!
我只是忘记了 java.exe 想要一个类名,而不是文件名!但我认为在注册表中没有办法做到这一点。

幸运的是,有一种解决方法,如果我们想要通用的话,仍然需要一个脚本文件来处理任何/所有类文件(当然,使用静态 main 函数!)。不是批次,我尽可能避免它们。我选择使用 WSH,因为它应该可以在任何现代 Windows 系统上使用。我也选择了做一个 JS 脚本,它也可以是一个 VB 脚本。

所以我制作了以下脚本(LaunchJavaClass.js):

if (WScript.Arguments.count() == 0)
{
  WScript.StdOut.Write("No parameters");
  WScript.Quit(1);
}
var className = WScript.Arguments.Item(0);
//~ WScript.StdOut.Write(className + "\n");
var m = className.match(/^(.*)\\(.+?)\.class$/);
if (m == null)
{
  WScript.StdOut.Write("Not a class file");
  WScript.Quit(1);
}
var classPath = m[1];
className = m[2];
//~ WScript.StdOut.Write(classPath + " >>> " + className + "\n");
var params = new Array();
for (i = 1; i < WScript.Arguments.count(); i++)
{
  params[params.length] = WScript.Arguments.Item(i);
}
var cmd = "cmd /c cd /D " + classPath + 
    " & C:/Java/jdk1.6.0_05/bin/java.exe " + 
    className + " " + params.join(" ");
//~ WScript.StdOut.Write(cmd + "\n");
var shell = WScript.CreateObject("WScript.Shell");
//~ var exec = shell.Exec(cmd); // Can be used to get stdout
shell.Run(cmd, 0);

我留下了一些输出,在这种情况下没有用,但可用于调试(使用 cscript 运行)。
当然,必须调整 JRE 的路径。

我更改了command注册表中的内容,如下所示:

[HKEY_CLASSES_ROOT\JavaClass\shell\open\command]
@="\wscript -b "D:\\_PhiLhoSoft\\WSH\\LaunchJavaClass.js\" %1 %*"

当然,调整路径,并保留上面的其他行。

现在,如果我将一些文件拖放到 .class 文件中,它会获取短文件路径作为 main() 函数的参数。

import java.io.*;

class TestDnD
{
 public static void main(String[] args)
 {
  Writer output = null;
  try
  {
   output = new BufferedWriter(new FileWriter(new File("LogFile.txt")));
   for (String arg : args)
   {
    output.write(arg + "\n");
   }
  }
  catch (IOException ioe)
  {
   ioe.printStackTrace();
   return;
  }
  finally
  {
    try { output.close(); } catch (IOException e) {}
  }
 }
}

我认为 .reg 文件的第一个版本可以用于其他用途,例如。在 .jar 文件上拖放(当然要适应它)。

这种技术用途有限:我们很少用 Java 编写一类程序!但这看起来是一个很好且有趣的挑战,所以我没有抗拒去解决它。-Djava.ext.dirs="some path;another path"注意:如果您需要使用外部库(在 jar 文件中),您可以添加一些东西。

于 2008-12-20T18:36:18.663 回答
0

Adding onto Adiel A. If you create a batch file, which launches your a Java window using Swing. You would have the user drop the files onto that window. You could then be able to root through those dropped files.

于 2008-12-20T04:22:01.760 回答
0

So there's no way to have windows itself pass the args into main() via drag and drop?

于 2008-12-20T04:34:30.750 回答