Changing file associations using Java - java

I have read that you can change the Windows file associations by using commands like assoc .pmdtb="X:\PassswordManager.bat", but I still have some problems with it.
When I run the command in the command line, then nothing changes. Files with this extension are still opened with Notepad.
When I try to run the command in Java, I am denied access.
How do I edit the Windows internal file associations in Java? If I should rather edit the registry directly, which of the many Classes directories?
My Java code:
Runtime.getRuntime().exec("cmd.exe /c assoc .pmdtb=\"X:\\PasswordManager.bat\"");
// --> Access denied.
Thanks in advance.

File associations will apparently no longer be changeable with assoc and ftype starting with Windows 8. A hash code is additionally in the registry, which is generated with a secret algorithm. If I change the file association, but the hash does not match, the default opening of this file extension will not change. The Windows algorithm for the hash has been reverse engineered. Based on this, you could translate the algorithm into Java and change the registry directly.
The C++ code with QT can be found here: https://pastebin.com/yVhWeQ3X

By far the simplest method is to use one of many FTA utilities that resolve the security hash for you.
For example https://danysys.com/set-file-type-association-default-application-command-line-windows-10-userchoice-hash-internal-method/
Then use that via a cmd line call from your java app
You may need to test out the options (read the comments on linked page above and review issues on github) however it could be as simple as
SFTA.exe --reg "X:\PassswordManager.bat" "pmdtb"

Related

How do i get the working directory of a windows process in java?

I would like to get the path to the working directory of a specific process (for example for the PID of the process). I am Not Talking about the working or current Directory of the process where my Java Code is running. Its a simple task with Linux, but for Windows i cant find a proper solution. Furthermore, it would be nice, if its a Command or a Framework for Java, because i will need the path in my Code. I am not looking for the path to the executable, also Not for a solution with wmic or process explorer.
Already thanks for the help.
I already tried commands like tlist and wmic, but those solutions cant be utilize in my code. I am looking for a solution that i can use without special installations on Windows.
JNI and JNA provide means to call directly into native libraries from Java code, and it is feasible to use these to call out to Windows libraries.
There is a github project that appears to be close to the need: https://github.com/kohsuke/winp. Perhaps you can add the needed code and send up a pull request, or fork the project.
Note that any solution here is going to be windows-specific, meaning the application using it will not run on another platform. Given the nature of the question, that doesn't sound like it would ever be a concern.

Proper method to find user's My Documents folder on Windows with Java?

For whatever reason, I sometimes need to find the current user's My Documents folder on Windows in a Java program to read some files. But as far as I can tell, there is no way to do it that isn't severely flawed.
The first wrong way: System.getProperty("user.home");
Why it won't work:
It only returns the \username\ folder; I'd need to add "\Documents\" on to the end to get the Documents folder... and that only works in English.
Sun bugs 6519127 and 4787931. Java finds the user home folder on Windows by reading a deprecated registry key* to find the Desktop then taking the parent; this method has multiple known problems that will easily cause a completely wrong folder to be returned. The bugs are 3.75 years and 8 years old with no fix.
The second wrong way: Using a registry-reading program to get the Personal folder of the user, which is My Documents (but i18n'd).
Why it won't work:
While it fixes the English-only problem, it's still using the same deprecated registry area, so the bugs still apply to it.
The deprecated registry key says to use a native call (SHGetKnownFolderPath) which I obviously can't do from Java.
The third wrong way:
JFileChooser fr = new JFileChooser();
FileSystemView fw = fr.getFileSystemView();
File documents = fw.getDefaultDirectory();
Why it won't work: It works great!
Except when it doesn't. While I had a program that used this open and running in the background, I opened a DirectX game (Fallout: New Vegas). The Java program immediately terminated with no stack trace. Always reproducible (for me on that game, and who knows what else). Couldn't find a Sun bug#.
So is there any method to find a user's Documents folder, on Windows, from Java, that doesn't have known problems?
(This is a nice big question.)
*(The key is "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
There's no pure java way to do it, but you could use the JNA wrapper over JNI to do it without having to write any native code yourself. There's a good example of how to get the Documents folder on Windows halfway down the responses at:
What is the best way to find the users home directory in Java?
A time consuming, but reliable way of finding the 'Documents' folder of a windows user: Make your java app execute a bat script that uses Reg.exe (a windows system file) to find the value of the reg key which has the path in it. Then use a pipeline in the same bat file to send that data to the 'findstr' function which windows command prompt has. Use another pipeline to output the returned value to a text file. Then, simply make your java app read that text file, and delete it once its done :) Worked well enough for me.
Code for the bat file:
# echo off
Title Find Documents Folder
Reg Query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" |findstr "Personal">>DocPath.dat
exit
There is a custom Java API that someone built (their website no longer works), but there code remains on Google Code:
http://winfoldersjava.googlecode.com/files/WinFoldersJava_1.1.zip
There are two DLL's that need to be referenced, one for each architecture(x86 and x64).
user.home is not "my documents", but users home folder, like on Unix ~/.
To get to "My documents" you can use System.getProperty("user.home")+"\Documents"; irrespective of the language system. Try it.

Platform independent way to fire off external applications/helpers by file type?

For example, one application that I'm working on stores PDF files into a database, then can pull them back out for display. I've got a call in there using Runtime.exec to do a "cmd /c start " plus the PDF filename. Works great for Windows. Would prefer to find a platform independent way (trying to avoid OS detection with alternate methods for various OS) to do this though as we also run the software on Solaris and Mac.
Look at Desktop which has a open method and that would be platform independent.
Launches the associated application to
open the file.
I'd be interested to see if there is a 'correct' answer for this. If I were to do this, I'd have a properties file mapping of OS to the command needed to run, and then resolve the OS at runtime.
Eg in a properties file:
windows=cmd /c start
mac=open #(I think)
linux=... etc

Utilising a file association in a Java application

I am in the process of writing a cross platform Swing based application in which I want to utilize a file association which has been registered with the OS.
So iv got to the point where I can click on a file and my app loads, but what I need to know is how I can get my application to know where the file is that launched it and then query the contents.
Is there something further I have to do with the file association registration? Or can Java do this for me?
I'm not positive, but I'd expect that the name of the file you're processing by file click will end up in the arguments to your main() method. Have you tried/checked that?
If this is on Windows (you didn't specify):
In the registry wherever you specified your application path for the file type registered to it, add to "%1". This is a special parameter Windows will fill in with the path of the file that was clicked. So your registry entry would look something like c:\path\to\app.exe "%1"
One way to do this is to have the file association run your Java app via a script or batch file, and have the batch file pass the pathname of the file as a command line argument, environment variable or Java property.
Extensions can be linked to applications, you can setup the registry keys during installation. Which keys you need is documented here:
http://support.microsoft.com/?scid=kb%3Ben-us%3B185453&x=6&y=11
From java you can't access the windows registry in a direct way.
Using Runtime you could do something like that
http://www.rgagnon.com/javadetails/java-0480.html
There're two commands on Windows that can help, assoc and ftype, so that you needn't do the dirty laundry to manipulate registry. Invoke the commands using, say, java.lang.Process. http://www.rgagnon.com/javadetails/java-0592.html

Change Directory in MATLAB from Terminal/JAVA

I need to be able to change the working directory in MATLAB without interacting with the command window. I'm launching MATLAB from a Java application. Right now the only solution I've come up with is closing MATLAB, changing directory from JAVA and relaunching. Is there some streamlined way to send MATLAB the 'cd' command from JAVA? Doing so from the command-line would also work, since I could use getRuntime().exec(command)
Thanks!
You can do this using JMI if you're using the same JVM as Matlab (if not then I have no idea). There is not much online info about this (it's WAY undocumented/unsupported). Google it or read this: http://www.cs.virginia.edu/~whitehouse/matlab/JavaMatlab.html. In short, you need to include Matlab's relevant JAR file and then use com.mathworks.jmi.Matlab's functionality. For example:
Matlab.evalConsoleOutput("cd('C:\Program Files\')");
Yair Altman
http://UndocumentedMatlab.com
I am working with Stephen Poletto who posted the original question. There wasn't any existing solution that met our needs so we wrote our own solution based off of Kamin Whitehouse's work mentioned by Yair. It is available for all to use at matlabcontrol.googlecode.com
It allows for controlling MATLAB from a Java program launched outside of MATLAB.

Categories