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

时间:2013-05-27 10:19:50

标签: java windows contextmenu

enter image description here

因此,我们的想法是制作一个仅适用于.txt个文件的加密软件,并在其上应用一些加密函数并生成一个新文件。为了避免用户不得不拖放文件的麻烦,我决定在这里做一个类似于我的反病毒的选项。

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

  1. 这些菜单名称是什么?我的意思是正确的名称,以便下次我能以更清晰的方式引用它们
  2. 如何制作这些?
  3. 我最初的理解:

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

1 个答案:

答案 0 :(得分:5)

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

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

<强>&LT; UPDATE&GT;
请参阅帖子末尾的示例代码链接和工作演示 的&LT; / UPDATE&GT;

需要做什么

  1. 我们需要编辑注册表,在我们感兴趣的文件类型的上下文菜单中添加一个额外的条目(对于我们的java-app)(例如.txt.doc.docx)。

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

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

    3. 我们需要在正确的注册表节点下插入正确的密钥,值和数据。

  2. 我们需要一个打包为.JAR文件的java-app,其中main方法期望一个String数组包含一个值,该值对应于我们需要处理的文件的路径(嗯,那& #39;是容易的部分 - 只是说明显而易见的事。)

  3. 所有这些说起来容易做起来难得(或者反之亦然?),所以让我们看看如何完成每一项工作。

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

    假设

    1. 我们假设目标文件类别是.TXT个文件 - 可以对每个文件类别应用相同的步骤。
    2. 如果我们希望更改(即上下文菜单)影响所有用户,我们需要编辑HKCR\下的注册表项(例如HKCR\txtfile),这需要管理权限。 为简单起见,我们假设只需要更改当前用户的设置,因此我们必须编辑HKCU\Software\Classes下的密钥(例如HKCU\Software\Classes\txtfile),这样做 not 需要管理权限。 如果选择进行系统范围的更改,则需要进行以下修改:
      1. 在所有REG ADD/DELETE命令中,将HKCU\Software\Classes\...替换为HKCR\...(在REG QUERY命令中执行替换它)。
      2. 让您的应用程序运行管理权限。这里有两个选项(我知道):
        • 提升正在运行的实例的权限(由于UAC,最新的Windows版本会更复杂)。 SO中有大量的在线资源; this one 似乎很有希望(但我自己还没有对它进行过测试)。
        • 要求用户明确地运行您的应用程序&#34;作为管理员&#34; (使用右键单击 - &gt;&#34;以管理员身份运行&#34;等)。
    3. 我们假设只需要简单的上下文菜单条目(而不是具有更多条目的上下文子菜单)。 经过一些(相当浅薄的)研究后,我开始相信在旧版Windows(XP,Vista)中添加子菜单需要更复杂的东西(ContextMenuHandlers等)。在Windows 7或更新版本中添加子菜单要容易得多。我在 this answer (提供的工作演示;))的相关部分中描述了该过程。
    4. 那就是说,让我们继续......

      完成任务

      1. 您可以通过发布REG Operation [Parameter List]表单的命令来实现对注册表的编辑,其中包含ADDDELETEQUERY的操作(稍后会详细介绍) 。 为了执行必要的命令,我们可以使用 ProcessBuilder 实例。例如。

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

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

        1. &#34;通常&#34;我们必须编辑.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的路径)超出了本答案的范围,但应该有很多方法可以做到(我不知道一个我会百分之百地信任。) 我只列出了一些我的头脑:

          • 寻找环境变量&#39; JAVA_HOME&#39; (System.getenv("java.home");)。
          • 在注册表中查找HKLM\Software\JavaSoft\Java Runtime Environment\<CurrentVersion>\JavaHome之类的值。
          • 查看预定位置(例如C:\Program Files[ (x86)]\Java\)。
          • 提示用户将其指向JFileChooser(对于没有经验的用户来说不是很好)。
          • 使用像Launch4J这样的程序将.JAR包装到.EXE中(这样就不需要确定自己的路径了。)
      2. 最新版本的Java(1.7 +?)在路径上放置了javaw.exe(以及其他实用程序)的副本,因此也可能需要检查它。

          3.因此,在收集了所有必要的数据之后,主要部分是:将所需的值插入到Registry中。完成此步骤后,我们的HKCU\Software\Classes\txtfile - 节点应如下所示:

        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)是否已经有一个名为&#34; MyCoolContextMenu&#34;的上下文菜单条目,或者我们可能覆盖现有的类似乎是一个好主意。条目(这不会让我们的用户非常高兴)。
        • 由于价值的数据部分(/d之后和/f之前的部分)需要包含在""中,请记住您可以逃避{{1在字符串内部"。 您还需要转义\",以便它按原样存储在注册表值中(将其转义为:%1)。
        • 最好为您的用户提供一个选项,以便取消注册&#34;你的上下文菜单条目。 可以通过以下命令实现取消注册:
          %%1
        • 在命令末尾省略REG DELETE HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu /f可能会提示用户&#34; (在这种情况下是你的应用程序)进行确认,在这种情况下你需要使用Process&#39; getOutputStream() 输出方法&#34;是&#34;为了完成操作。 我们可以使用强制标记(/f)来避免不必要的交互。

        几乎就在那里!

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

        1. 为类别/f中的文件注册的上下文菜单条目(请注意,它不仅限于.TXT文件,而是适用于系统所涉及的所有文件&#34; txtfiles&#34;)
        2. 点击该条目后,我们的java-app应该运行,其txtfile方法传递一个String数组,其中包含右键单击的.TXT文件的路径。
        3. 从那里,我们的应用程序可以接管并发挥其魔力:)

          那几乎所有人,伙计们!

          对不起,对于长篇文章。我希望结果对某人有用 我会尽快添加一些演示代码(尽管没有承诺;))。

          更新

          演示准备好了!