4

在此处输入图像描述

所以我们的想法是制作一个只对.txt文件起作用的加密软件,并在其上应用一些加密功能并生成一个新文件。为了避免用户不得不拖放文件的麻烦,我决定在这里设置一个类似于我的防病毒软件的选项。

我想学习如何为各种操作系统制作这些,无论架构如何:)

  1. 这些菜单叫什么?我的意思是正确的名称,所以下次我可以以更清晰的方式提及它们
  2. 如何制作这些?

我的初步理解:

我认为它会做的是:将文件作为参数传递给main()方法,然后将其余的处理留给我:)

4

1 回答 1

5

可能不完全是您希望的答案,但似乎这是一个相当复杂的问题。无论如何,我将分享我对它的了解,希望它足以(至少)让你开始。

不幸的是,使用 Java 创建上下文菜单的最简单方法是编辑注册表。我将尝试总结实现我们目标的总体要求和步骤的里程碑。

<更新>
请参阅文章末尾的示例代码和工作演示的链接。
</更新>

需要做什么

  1. 我们需要编辑注册表,在我们感兴趣的文件类型(例如,、、)的上下文菜单中添加一个附加条目(用于我们的 java 应用.txt程序.doc.docx

    1. 我们需要确定要编辑注册表中的哪些条目,因为我们的目标文件扩展名可能与另一个“类”相关联(我无法在 XP 上对其进行测试,但在 Windows 7/8 上似乎就是这种情况)。例如,...\Classes\.txt我们可能需要编辑...\Classes\txtfile.txtClass 相关联的,而不是编辑。

    2. 我们需要指定已安装 jre 的路径(除非我们可以确定包含的目录javaw.exe在 PATH 变量中)。

    3. 我们需要在适当的注册表节点下插入适当的键、值和数据。

  2. 我们需要一个打包为 .JAR 文件的 java-app,其main方法需要一个 String 数组,其中包含一个值,该值对应于我们需要处理的文件的路径(嗯,这是最简单的部分 - 只是说明显而易见的)。

所有这一切说起来容易做起来难(或者相反?),所以让我们看看完成每一个需要什么。

首先,我们将为这篇文章的其余部分做出一些假设(为了简单/清晰/简洁等)。

假设

  1. 我们假设目标文件类别是.TXT文件——可以对每个文件类别应用相同的步骤。
  2. 如果我们希望更改(即上下文菜单)影响所有用户,我们需要编辑HKCR\(例如HKCR\txtfile)下的注册表项,这需要管理权限。为简单起见,我们假设只需要更改当前用户的设置,因此我们将不得不编辑HKCU\Software\Classes(例如HKCU\Software\Classes\txtfile)下的键,这不需要管理权限。如果选择进行系统范围的更改,则需要进行以下修改:
    1. 在所有REG ADD/DELETE命令中,替换HKCU\Software\Classes\...HKCR\...(不要命令中替换它REG QUERY)。
    2. 让您的应用程序以管理权限运行。这里有两个选项(我知道):
      • 提升您正在运行的实例的权限(由于 UAC,使用最新的 Windows 版本可能会更复杂)。网上和这里有很多资源;这个看起来很有希望(但我自己没有测试过)。
      • 要求用户明确地“以管理员身份”运行您的应用程序(使用右键单击 ->“以管理员身份运行”等)。
  3. 我们假设只需要简单的上下文菜单条目(与具有更多条目的上下文子菜单相反)。经过一些(相当肤浅的)研究,我开始相信在旧版本的 Windows(XP、Vista)中添加子菜单需要更复杂的东西(ContextMenuHandlers 等)。在 Windows 7 或更高版本中添加子菜单要容易得多。我在这个答案的相关部分描述了这个过程(提供了工作演示;))。

话虽如此,让我们继续...

把事情做好

  1. 您可以通过发出形式的命令来实现对注册表的编辑REG Operation [Parameter List],操作涉及ADD, DELETE, QUERY(稍后会详细介绍)。为了执行必要的命令,我们可以使用ProcessBuilder实例。例如

    String[] cmd = {"REG", "QUERY", "HKCR\\.txt", "/ve"};
    new ProcessBuilder(cmd).start();
    // Executes: REG QUERY HKCR\.txt /ve

    当然,我们可能希望捕获并进一步处理命令的返回值,这可以通过相应的 Process'getInputStream()方法来完成。但这属于范围“实施细节”......

    1. “通常”我们必须编辑.txt文件类,除非它与另一个文件类相关联。我们可以使用以下命令对此进行测试:

      // This checks the "Default" value of key 'HKCR\.txt'
      REG QUERY HKCR\.txt /ve

      // Possible output:
      (Default) REG_SZ txtfile

      我们只需要解析上面的输出并找出默认值是否为空或包含类名。在这个例子中我们可以看到关联的类是txtfile,所以我们需要编辑节点HKCU\Software\Classes\txtfile

    2. 指定 jre 路径(更准确地说是路径javaw.exe)不在此答案的范围内,但应该有很多方法可以做到这一点(我不知道我会 100% 信任的方法)。
      我只列出我脑海中的一些:

      • 寻找环境变量 'JAVA_HOME' ( System.getenv("java.home");)。
      • 在注册表中查找类似HKLM\Software\JavaSoft\Java Runtime Environment\<CurrentVersion>\JavaHome.
      • 查看预定义的位置(例如C:\Program Files[ (x86)]\Java\)。
      • 提示用户在 JFileChooser 中指出它(对于没有经验的用户来说不是很好)。
      • 使用 Launch4J 之类的程序将您的 .JAR 包装到 .EXE 中(这样就无需自己确定“javaw.exe”的路径)。

最新版本的 Java(1.7+ ?)将(和其他实用程序)的副本javaw.exe放在路径上,因此可能也值得检查。

3. 因此,在收集了所有必要的数据之后,主要部分是:将所需的值插入注册表。编译完这一步后,我们的HKCU\Software\Classes\txtfile-node 应该是这样的:

HKCU
|_____Software
      |_____Classes
            |_____txtfile
                  |_____Shell
                        |_____MyCoolContextMenu: [Default] -> [Display name for my menu-entry]
                              |_____Command: [Default] -> [<MY_COMMAND>]*

*: in this context, a '%1' denotes the file that was right-clicked.

根据您处理步骤 (1.2) 的方式,该命令可能如下所示:
"C:\Path\To\javaw.exe" -jar "C:\Path\To\YourApp.jar" "%1"
请注意,javaw.exe它通常在...\jre\bin\(但并非总是那里——最近我也一直在找到它C:\Windows\System32\)。

还是在步骤(1.3)中,我们需要执行的命令,为了实现上面的结构,如下图:

REG ADD HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu /ve /t REG_SZ /d "Click for pure coolness" /f
REG ADD HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu\Command /ve /t REG_SZ /d "\"C:\Path\To\javaw.exe\" -jar \"C:\Path\To\Demo.jar\" \"%%1\" /f"

        // Short explanation:
        REG ADD  <Path\To\Key>  /ve  /t REG_SZ  /d "<MY_COMMAND>"  /f
        \_____/  \___________/  \_/  \_______/  \_______________/  \_/
 __________|_______   |          |       |___           |           |
|Edit the Registry |  |   _______|________   |   _______|_______    |
|adding a key/value|  |  |Create a no-name|  |  |Set the data   |   |
--------------------  |  |(default) value |  |  |for this value.|   |
                      |  ------------------  |  |Here: a command|   |
       _______________|______________        |  |to be executed.|   |
      |Edit this key                 |       |  -----------------   |
      |(creates the key plus         |   ____|_________    _________|_____
      | any missing parent key-nodes)|  |of type REG_SZ|  |No confirmation|
      --------------------------------  |(string)      |  -----------------
                                        ----------------

实施注意事项

  • 检查我们的目标类(例如txtfile)是否已经有一个名为“MyCoolContextMenu”的上下文菜单条目可能是一个好主意,否则我们可能会覆盖现有条目(这不会让我们的用户非常高兴)。
  • 由于值的数据部分(在 之后/d和之前的部分/f)需要包含在 中"",请记住,您可以"在字符串中转义为\". 您还需要转义,%1以便它按原样存储在注册表值中(转义为:)%%1
  • 为您的用户提供“取消注册”您的上下文菜单条目的选项是个好主意。注销可以通过以下命令实现:
    REG DELETE HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu /f
  • 省略/f命令末尾的 可能会提示“用户”(在这种情况下是您的应用程序)进行确认,在这种情况下,您需要使用 ProcessgetOutputStream()方法输出“是”才能完成操作。我们可以使用强制标志 ( /f) 来避免这种不必要的交互。

差不多好了 !

在步骤 (2) 中,我们现在应该有以下内容:

  1. 在类别中为我们的文件注册的上下文菜单条目txtfile(请注意,它不限于 .TXT 文件,而是适用于系统作为“txtfiles”的所有文件)。
  2. 单击该条目后,我们的 java-app 应该会运行,并且它的main()方法传递了一个字符串数组,其中包含指向右键单击的 .TXT 文件的路径。

从那里,我们的应用程序可以接管并发挥它的魔力:)

这就是(几乎)全部,伙计们!

抱歉,帖子太长了。我希望它对某人有用。
我会尽快添加一些演示代码(虽然没有承诺;))。

更新

演示已准备就绪!

于 2013-05-28T08:56:21.603 回答