如何为我的软件制作上下文菜单?

Lit*_*ild 4 java windows contextmenu

在此处输入图片说明

因此,我们的想法是制作一种仅在.txt文件上运行并在其上应用一些加密功能并生成新文件的加密软件。为了避免用户不得不拖放文件的麻烦,我决定在此处做出一个与我的防病毒类似的选项。

我想学习如何针对各种OS制作这些文件,无论其体系结构是什么:)

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

我的初步理解:

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

gka*_*pak 5

可能不完全是您希望的答案,但这似乎是一件相当复杂的事情。无论如何,我将分享我对它的了解,并且希望它将证明足以(至少)使您入门。

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

<UPDATE>
请参阅文章末尾的示例代码链接和有效的演示。
</ UPDATE>

需要做什么

  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版本可能会更加复杂)。SO上有很多在线资源。这个似乎很有希望(但是我自己还没有测试过)。
      • 要求用户以“以管理员身份”显式运行您的应用程序(使用右键单击->“以管理员身份运行”等)。
  3. 我们假设只需要简单的上下文菜单项(与具有更多条目的上下文子菜单相对)。经过一些(相当浅薄的)研究,我开始相信在较旧版本的Windows(XP,Vista)中添加子菜单将需要更复杂的内容(ContextMenuHandlers等)。在Windows 7或更高版本中添加子菜单要容易得多。我在此答案的相关部分中描述了该过程(提供了工作演示;)。

也就是说,让我们继续...

把事情做好

  1. 您可以实现通过发行形式的命令编辑注册表REG Operation [Parameter List],业务涉及ADDDELETEQUERY(稍后更多)。为了执行必要的命令,我们可以使用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,因此我们需要编辑node 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.
Run Code Online (Sandbox Code Playgroud)

根据您对步骤(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)      |  -----------------
                                        ----------------
Run Code Online (Sandbox Code Playgroud)

实施注意事项

  • 检查我们的目标类(例如txtfile)是否已经有一个名为“ MyCoolContextMenu”的上下文菜单条目,或者我们可能会覆盖现有的条目(这不会使我们的用户感到满意),这可能是一个好主意。
  • 由于需要将值的数据部分(后面/d和之前的部分/f)括起来"",因此请记住,您可以"在字符串内转义\"。您还需要对进行转义,%1以便将其按原样存储在注册表值中(如:进行转义%%1)。
  • 最好为您的用户提供一个“注销”上下文菜单项的选项。可以通过以下命令取消注册:
    REG DELETE HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu /f
  • /f在命令末尾省略可能会提示“用户”(在这种情况下为您的应用)进行确认,在这种情况下,您需要使用Process' getOutputStream()方法输出“是”才能完成操作。我们可以使用force标志(/f)避免不必要的交互。

差不多好了 !

在步骤(2)中找到自己,我们现在应该具有以下内容:

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

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

差不多了,伙计们!

抱歉,很长的帖子。我希望它对某人有用。
我将尝试尽快添加一些演示代码(尽管没有承诺;)。

更新

演示已准备就绪!