如何为我的软件制作上下文菜单? [英] How do I make context menus for my software?

查看:113
本文介绍了如何为我的软件制作上下文菜单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So the idea is to make an encryption software which will work only on .txt files and apply some encryption functions on it and generate a new file. To avoid the hassle of user having to drag-and-drop the file, I have decided to make an option similar to my anti-virus here.

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

I want to learn how to make these for various OS, irrespective of the architecture :)


  1. 这些菜单叫什么?我的意思是正确的名称,以便下次我能以更清晰的方式引用它们

  2. 如何制作这些?

  1. What are these menus called? I mean the proper name so next time I can refer to them in a more articulate way
  2. How to make these?



我的初步理解:



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

My initial understanding:

What I think it will do is: pass the file as an argument to the main() method and then leave the rest of the processing to me :)

推荐答案

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

Probably not exactly the answer you were hoping for, but it seems that this is a rather complicated matter. Anyway, I'll share what I know about it and it will hopefully prove enough to (at least) get you started.

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

Unfortunately, the easiest way to create a context menu using Java is editing the Registry. I'll try to summarize the milestones of the overall requirements and steps to achieve our objective.

< UPDATE>

请在帖子末尾查看示例代码和工作演示的链接。

< / UPDATE>


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


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

  1. We need to determine which entries in Registry to edit, because our targeted file-extensions might be associated with another 'Class' (I couldn't test it on XP, but on Windows 7/8 this seems to be the case). E.g. instead of editing ...\Classes\.txt we might need to edit ...\Classes\txtfile, which the .txt Class is associated with.

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

We need to specify the path to the installed jre (unless we can be sure that the directory containing javaw.exe is in the PATH variable).

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

We need to insert the proper keys, values and data under the proper Registry nodes.


  • 我们需要一个打包为.JAR文件的java-app,带有 main 方法,期望一个String数组包含一个值,该值对应于我们需要的文件路径过程(嗯,这是最简单的部分 - 只是陈述显而易见的事情)。

  • We need a java-app packaged as a .JAR file, with a main method expecting a String array containing one value that corresponds to the path of the file we need to process (well, that's the easy part - just stating the obvious).

    所有这些说起来容易做起来难(或者它是相反的方式?),所以让我们看看如何完成每一个。

    All this is easier said than done (or is it the other way around ?), so let's see what it takes to get each one done.

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

    First of all, there are some assumption we'll be making for the rest of this post (for the sake of simplicity/clarity/brevity and the like).


    1. 我们假设目标文件类别是 .TXT 文件 - 可以对每个文件类别应用相同的步骤。

    2. 如果我们希望更改(即上下文菜单)影响所有用户,我们需要编辑 HKCR \ 下的注册表项(例如 HKCR\txtfile ),这需要管理权限。
      为简单起见,我们假设只需要更改当前用户的设置,因此我们必须在 HKCU \Software \Class 下编辑密钥。 (例如 HKCU \Software\Classes \txtfile ),需要管理权限。
      如果选择进行系统范围的更改,则需要进行以下修改:

    1. We assume that the target file-category is .TXT files - the same steps could be applied for every file-category.
    2. If we want the changes (i.e. context-menus) to affect all users, we need to edit Registry keys under HKCR\ (e.g. HKCR\txtfile), which requires administrative priviledges. For the sake of simplicity, we assume that only current user's settings need to be changed, thus we will have to edit keys under HKCU\Software\Classes (e.g. HKCU\Software\Classes\txtfile), which does not require administrative priviledges. If one chooses to go for system-wide changes, the following modifications are necessary:

    1. 在所有 REG ADD /中删除命令,将 HKCU \Software \Classes \ ... 替换为 HKCR \ ... REG QUERY 命令中替换它。)

    2. 拥有你的应用程序运行管理权限。这里有两个选项(我知道):


      • 提升正在运行的实例的权限(由于UAC,最新的Windows版本会更复杂)。 SO中有大量的在线资源; 这一个 似乎很有希望(但我没有'我自己测试了。)

      • 要求用户明确地以管理员身份运行您的应用程序(使用右键单击 - >以管理员身份运行等)。

    1. In all REG ADD/DELETE commands, replace HKCU\Software\Classes\... with HKCR\... (do not replace it in REG QUERY commands).
    2. Have your application run with administrative priviledges. Two options here (that I am aware of):
      • Elevate your running instance's priviledges (can be more complicated with latest windows versions, due to UAC). There are plenty of resources online and here in SO; this one seems promising (but I haven't tested it myself).
      • Ask the user to explicitely run your app "As administrator" (using right-click -> "Run as administrator" etc).


  • 我们假设只需要简单的上下文菜单条目(而不是具有更多内容的子菜单子菜单)项)。
    经过一些(相当浅薄的)研究后,我开始相信在旧版Windows(XP,Vista)中添加子菜单需要更复杂的东西(ContextMenuHandlers等)。在Windows 7或更新版本中添加子菜单要容易得多。我在 这个答案的相关部分描述了该过程 (提供工作演示;))。

  • 这就是说,让我们继续......

    That said, let's move on to...


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

    1. You can achieve editing the Registry by issuing commands of the form REG Operation [Parameter List], with operations involving ADD, DELETE, QUERY (more on that later). In order to execute the necessary commands, we can use a ProcessBuilder instance. E.g.

    String [] cmd = {REG,QUERY,HKCR\\.txt,/ ve} ;

    new ProcessBuilder(cmd).start();

    //执行:REG QUERY HKCR\.txt / ve

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

    Of course, we will probably want to capture and further process the command's return value, which can be done via the respective Process' getInputStream() method. But that falls into scope "implementation details"...


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

    1. "Normally" we would have to edit the .txt file-class, unless it is associated with another file-class. We can test this, using the following command:

    //这将检查密钥'HKCR\.txt'的默认值

    REG QUERY HKCR\.txt / ve

    //可能的输出:

    (默认)REG_SZ txtfile

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

    All we need, is parse the above output and find out, if the default value is empty or contains a class name. In this example we can see the associated class is txtfile, so we need to edit node HKCU\Software\Classes\txtfile.

    指定jre路径(更准确地说是指向 javaw.exe 的路径)超出了这个答案的范围,但应该有很多方法可以做到(我不知道我会100%信任的那个)。

    我只会列出一些关于我的头脑:

    Specifying the jre path (more precisely the path to javaw.exe) falls outside the scope of this answer, but there should be plenty of ways to do it (I don't know of one I would 100% trust though).
    I'll just list a few off the top of my head:


    • 寻找环境变量'JAVA_HOME'( System.getenv(java.home) ); )。

    • 在注册表中查找类似 HKLM \Software\JavaSoft \ Java运行时环境的值\\< CURRENTVERSION> \JavaHome

    • 查看预定位置(例如 C:\Program Files [(x86)] \ Java \ )。

    • 提示用户将其指向JFileChooser(对于没有经验的用户来说非常好)。

    • 使用像Launch4J这样的程序来包装你的.JAR转换为.EXE(无需自己确定'javaw.exe'的路径)。

    • Looking for environment-variable 'JAVA_HOME' (System.getenv("java.home");).
    • Looking in the Registry for a value like HKLM\Software\JavaSoft\Java Runtime Environment\<CurrentVersion>\JavaHome.
    • Looking in predifined locations (e.g. C:\Program Files[ (x86)]\Java\).
    • Prompting the user to point it out in a JFileChooser (not very good for the non-experienced user).
    • Using a program like Launch4J to wrap your .JAR into a .EXE (which eliminates the need of determining the path to 'javaw.exe' yourself).


    最新版本的Java(1.7+?)放了一份 javaw.exe (和其他实用程序)在路径上,所以也可能值得检查。




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

    Latest versions of Java (1.7+ ?) put a copy of javaw.exe (and other utilities) on the path, so it might be worth checking that as well.

    3. So, after collecting all necessary data, comes the main part: Inserting the required values into Registry. After compliting this step, our HKCU\Software\Classes\txtfile-node should look like this:

    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-jarC:\ Path\To \YourApp.jar%1

    请注意 javaw.exe 通常位于 ... \ jre \ bin \ (但并非总是 - 最近我一直在 C:\ Windows \ System32 \ 同样)。

    Based on how you addressed step (1.2), the command could look like this:
    "C:\Path\To\javaw.exe" -jar "C:\Path\To\YourApp.jar" "%1"
    Note that javaw.exe is usually in ...\jre\bin\ (but not always only there - recently I've been finding it in C:\Windows\System32\ as well).

    仍然在步骤(1.3)中,为了实现上述结构,我们需要执行的命令看起来像如下:

    Still being in step (1.3), the commands we need to execute, in order to achieve the above structure, look as follows:

    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 可能会提示用户(在此例如你的应用程序)进行确认,在这种情况下你需要使用进程' getOutputStream() 输出是的方法,以便操作完成。
      我们可以使用强制标志( / f )来避免不必要的交互。

    • It is probably a good idea to check if our target class (e.g. txtfile), does already have a context-menu entry named "MyCoolContextMenu", or else we might be overriding an existing entry (which will not make our user very happy).
    • Since the data part of the value (the part that comes after /d and before /f) needs to be enclosed in "", keep in mind that you can escape " inside the string as \". You also need to escape the %1 so that it is stored in the Registry value as-is (escape it like: %%1).
    • It is a good idea to provide your user with an option to "un-register" your context-menu entry. The un-registering can be achieved by means of the command:
      REG DELETE HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu /f
    • Omitting the /f at the end of the commands may prompt the "user" (in this case your app) for confirmation, in which case you need to use the Process' getOutputStream() method to output "Yes" in order for the operation to be completed. We can avoid that unnecessary interaction, using the force flag (/f).

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

    Finding ourselves at step (2), we should by now have the following:


    1. 在类别 txtfile 中为我们的文件注册的上下文菜单条目(请注意,它不限于.TXT文件,但适用于系统所关联的所有文件为txtfiles)。

    2. 点击该条目后,我们的java-app应该运行,其 main()方法传递一个String数组,其中包含右键单击的.TXT文件的路径。

    1. A context-menu entry registered for our files in category txtfile (note that it is not restricted to .TXT files, but applies to all files pertained by the system as "txtfiles").
    2. Upon clicking that entry, our java-app should be run and its main() method passed a String array containing the path to the right-clicked .TXT file.

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

    From there, our app can take over and do its magic :)

    抱歉,对于长篇文章。我希望它对某人有用。

    我会尽快添加一些演示代码(尽管没有承诺;))。

    Sorry, for the long post. I hope it turns out to be of use to someone.
    I'll try to add some demo-code soon (no promises though ;)).

    更新

    演示就绪!

    • I created a tiny demo-project.
    • Here is the source code.
    • Here is a ready-to-go JARred App.

    这篇关于如何为我的软件制作上下文菜单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆