How to create a context menu for my software?

enter image description here

So, the idea is to make encryption software that will only work in .txt files and apply some encryption functions to it and generate a new file. To avoid the problems of the user who has to drag and drop the file, I decided to make here an option similar to my antivirus.

I want to learn how to make them for different OS, regardless of architecture :)

  • What are these menus called? I mean my own name, so next time I can refer to them more clearly.
  • How to do it?

My initial understanding:

I think this will be done: pass the file as an argument to the main() method, and then leave the rest of the processing to me :)

+4
source share
1 answer

Probably not exactly the answer you were hoping for, but it seems to be a pretty tricky question. In any case, I will share what I know about it, and I hope that it will be enough for you to start (at least).

Unfortunately, the easiest way to create a context menu using Java is to edit the registry. I will try to summarize the main stages of the general requirements and steps to achieve our goal.

<UPDATE>
See the end of the post for links to sample code and a working demo.
</ UPDATE>

What should be done

  • We need to change the registry by adding an additional entry (for our java application) to the context menus of the file types of interest to us (for example, .txt , .doc , .docx ).

    • We need to determine which registry entries will be edited, because our target file extensions may be associated with another “class” (I could not test it on XP, but in Windows 7/8 it looks like this). For instance. instead of editing ...\Classes\.txt we may need to edit ...\Classes\txtfile , with which the .txt class is associated.

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

    • We need to insert the correct keys, values ​​and data into the corresponding registry nodes.

  • We need a java application packaged as a .JAR file, with the main method waiting for a String array containing one value that corresponds to the path of the file that we need to process (well, that’s just the part - just indicating the obvious).

Is all this easier said than done (or vice versa)? So let's see what needs to be done to make each.

First of all, there are some assumptions that we will make for the rest of this post (for simplicity / clarity / brevity, etc.).

Assumptions

  • We assume that the target file category is .txt files - the same steps can be applied to each file category.
  • If we want changes (for example, context menus) to affect all users, we need to change the registry keys under HKCR\ (for example, HKCR\txtfile ), which requires administrative privileges. For simplicity, we assume that we need to change only the current user settings, so we will need to edit the keys under HKCU\Software\Classes (for example, HKCU\Software\Classes\txtfile ), which requires non- administrative privileges. If you decide to switch to system-wide changes, the following changes are needed:
    • In all REG ADD/DELETE commands, replace HKCU\Software\Classes\... with HKCR\... (do not replace it in REG QUERY commands).
    • Ask your application to work with administrative privileges. There are two options here (what I know):
      • Raise your privileges to run (it may be more difficult with the latest versions of windows, due to UAC). There are many resources online here in SO; this one seems promising (but I have not tested it myself).
      • Ask the user to explicitly launch the “As administrator” application (using the right mouse button → “Run as administrator”, etc.).
  • We assume that only simple elements of the context menu are needed (as opposed to the context submenu with a large number of entries). After some (rather small) studies, I came to the conclusion that adding more submenus in older versions of Windows (XP, Vista) would require more complex material (ContextMenuHandlers, etc.). Adding a submenu in Windows 7 or later is much easier. I described the process in the relevant part of this answer (working demo provided;)).

Nevertheless, we pass to ...

Performance of work

  • You can edit the registry by issuing commands of the form REG Operation [Parameter List] , with operations involving ADD , DELETE , QUERY (more on this later). To execute the necessary commands, we can use an instance of ProcessBuilder . For instance.

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

    Of course, we probably want to capture and process the return value of the command, which can be executed through the corresponding getInputStream() process. But this falls into the scope of "implementation details" ...

    • “Normally” we would have to edit the .txt file class if it is associated with another file class. We can verify this using the following command:

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

      // Possible output:
      (Default) REG_SZ txtfile

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

    • Setting the jre path (more precisely, the path to javaw.exe ) is beyond the scope of this answer, but there should be many ways to do this (I do not know any, I would be 100% trusted, though).
      I just listed a few from my head:

      • We are looking for the environment variable 'JAVA_HOME' ( System.getenv("java.home"); ).
      • Looking at the registry for a value like HKLM\Software\JavaSoft\Java Runtime Environment\<CurrentVersion>\JavaHome .
      • Search in predefined locations (for example, C:\Program Files[ (x86)]\Java\ ).
      • Requesting the user to specify it in JFileChooser (not very good for an inexperienced user).
      • Using a program like Launch4J to transfer your .JAR to .EXE (which eliminates the need to determine the path to "javaw.exe" yourself).

Recent versions of Java (1.7+?) javaw.exe copy of javaw.exe (and other utilities) in the path, so check this out as well.



3. So, after collecting all the necessary data, the main part is: Insert the necessary values ​​into the registry. After completing 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. 

Based on how you solved step (1.2), the command might look like this:
"C:\Path\To\javaw.exe" -jar "C:\Path\To\YourApp.jar" "%1"
Note that javaw.exe usually located in ...\jre\bin\ (but not always only ) - I recently found it in C:\Windows\System32\ ).

Still at step (1.3), the commands that we need to execute to achieve the above structure are 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) | ----------------- ---------------- 

Implementation Recommendations :

  • It is probably a good idea to check if our target class (for example, txtfile ) has a context menu item named "MyCoolContextMenu", otherwise we could override the existing record (which will not make our user very happy).
  • Since the data part of the value (the part that comes after /d and before /f ) must be enclosed in "" , keep in mind that you can avoid " inside the line as \" . You also need to avoid %1 so that it is stored in the as-is registry value (take it like this: %%1 ).
  • It is a good idea to give your user the option to “re-register” your entry in the context menu. Without registration can be achieved using the command:
    REG DELETE HKCU\Software\Classes\txtfile\Shell\MyCoolContextMenu /f
  • By omitting /f at the end of the commands, you can ask for “user” (in this case your application) for confirmation, in which case you need to use “ getOutputStream() to print“ Yes ”to complete the operation. We can avoid this unnecessary interaction, using the force flag ( /f ).

Almost there!

At step (2), we should now have the following:

  • A context menu entry registered for our files in the txtfile category (note that it is not limited to .TXT files, but applies to all files belonging to the system as "txtfiles").
  • After clicking this entry, our java application should be launched, and the main() method passed a String array containing the path to the .TXT file with a right-click.

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

That’s (almost) everything, people!

Sorry for the long post. Hope this proves helpful to someone. I will try to add a demo code soon (no promises though;)).

UPDATE

The demo is ready!

+4
source

Source: https://habr.com/ru/post/1482942/


All Articles