I wish to launch the Windows 10 Store App Paint3D and make it open a JPG image. I'll be using Java but would be happy to see CMD / C# / Windows API answers. This isn't a question about how to use ProcessBuilder
.
Unlike the standard MS Paint application, Paint3D is from Windows Store and does not have Windows executable or alias. Paint3D does support launch url-protocol ms-paint:
which can be used in a web browser or launched from Windows CMD.EXE as start ms-paint:
.
This code shows 2 ways I've tried to launch Paint3D, one opens Paint3D correctly - but uses mspaint.exe, and the second opens Paint3D but with no image.
Does anyone have an idea whether it is possible to run Paint3D to open with JPG without launching via mspaint.exe?
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
public class LaunchPaint3D
{
public static void exec(String[] cmd) throws InterruptedException, IOException
{
System.out.println("exec "+Arrays.toString(cmd));
Path tmpdir = Path.of(System.getProperty("java.io.tmpdir"));
ProcessBuilder pb = new ProcessBuilder(cmd);
Path out = tmpdir.resolve(cmd[0]+"-stdout.log");
Path err = tmpdir.resolve(cmd[0]+"-stderr.log");
pb.redirectError(out.toFile());
pb.redirectOutput(err.toFile());
Process p = pb.start();
int rc = p.waitFor();
System.out.println("Exit "+rc +' '+(rc == 0 ? "OK":"**** ERROR ****")
+" STDOUT \""+Files.readString(out)+'"'
+" STDERR \""+Files.readString(err)+'"');
System.out.println();
}
public static void main(String[] args) throws InterruptedException, IOException
{
var jpg = Path.of(args[0]).toAbsolutePath();
System.out.println("Open "+jpg+" isRegularFile="+Files.isRegularFile(jpg));
String[] cmdA = new String[] {"mspaint.exe", jpg.toString()+" /ForceBootstrapPaint3D"};
String[] cmdB = new String[] {"cmd", "/c", "start", "ms-paint:", jpg.toString()};
// Also tried String[] cmdB = new String[] {"cmd", "/c", "start", "ms-paint:"+jpg.toString()};
System.out.println("Open Paint3D using MS-PAINT.EXE");
exec(cmdA);
System.out.println("PRESS RETURN");
System.in.read();
System.out.println("Open Paint3D using URL-PROTOCOL");
exec(cmdB);
System.out.println("END");
}
}
Example test run of the above:
Open c:\temp\small.jpg isRegularFile=true
Open Paint3D using MS-PAINT.EXE
exec [mspaint.exe, c:\temp\small.jpg /ForceBootstrapPaint3D]
Exit 0 OK STDOUT "" STDERR ""
PRESS RETURN
Open Paint3D using URL-PROTOCOL
exec [cmd, /c, start, ms-paint:, c:\temp\small.jpg]
Exit 0 OK STDOUT "" STDERR ""
END
I have found a solution which uses the old Paint application which supports launching to Paint 3D with the passed file argument. The Windows registry also shows this mechanism is used within Windows for editing various image file types such as JPG:
Computer\HKEY_CLASSES_ROOT\SystemFileAssociations\.jpg\Shell\3D Edit\command
=>
%SystemRoot%\system32\mspaint.exe "%1" /ForceBootstrapPaint3D
Run from CMD.EXE:
mspaint "C:\TEMP\A.jpg" /ForceBootstrapPaint3D
Java equivalent:
new ProcessBuilder("mspaint.exe", "c:\\TEMP\\A.jpg /ForceBootstrapPaint3D" ).start()