0

I have a cross-platform application created using Compose Multiplatform. I need to add it to SendTo menu (this menu is available in Windows Explorer when user right-clicked a file).

I've tried to find any options to implement it using Gradle. But there is no special options in nativeDistributions/windows.

I've also tried to implement it on application launch in main() function with the code below:

val appPath = Paths.get("C:/Program Files/MyApp/MyApp.exe")
val sendToDir = Paths.get(System.getenv("APPDATA"), "Microsoft", "Windows", "SendTo")
val shortcutPath = sendToDir.resolve("MyApp.lnk")
Files.createLink(shortcutPath, appPath)

It doesn't work and throws an exception:

java.nio.file.AccessDeniedException: C:\Users\Me\AppData\Roaming\Microsoft\Windows\SendTo\MyApp.lnk -> C:\Program Files\MyApp\MyApp.exe
    at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:89)
    at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
    at java.base/sun.nio.fs.WindowsFileSystemProvider.createLink(WindowsFileSystemProvider.java:622)
    at java.base/java.nio.file.Files.createLink(Files.java:1112)

How to create shortcut in Windows SendTo directory using Compose Multiplatform?

BArtWell
  • 4,176
  • 10
  • 63
  • 106

1 Answers1

2

The Windows folder with sendTo links is not administrator-permission protected:

%APPDATA%\Microsoft\Windows\SendTo

Just create a link there to the application you want to run.

EDIT 1

Try creating a .lnk file. It has a binary format, so a java lib like mslinks should help you accomplishing this task programatically:

https://github.com/DmitriiShamrikov/mslinks

The documentation says Files.createLink creates hard links, which can be a problem since Program Files is a folder protected with admin privileges.

EDIT2

Write a .vbs file with these lines and call the shell to run if from your app. It will create the .lnk file using native Windows components (VBScript):

Set WshShell = CreateObject("WScript.Shell")
Set oShellLink = WshShell.CreateShortcut(WshShell.ExpandEnvironmentStrings("%APPDATA%") & "\Microsoft\Windows\SendTo\MyApp.lnk")
oShellLink.TargetPath = "C:\Program Files\MyApp\MyApp.exe"
oShellLink.Save

You can delete the .vbs file after the script is finished.

Eduardo Poço
  • 2,819
  • 1
  • 19
  • 27
  • But it's thrown AccessDeniedException. I've updated the question text, please check it. – BArtWell Apr 24 '23 at 14:17
  • Files.createLink creates a hard link, which may have problems in some OSs. Try creating a normal windows link manually first to see if it works, or if there is some other problem preventing the folder from being accessed. – Eduardo Poço Apr 24 '23 at 16:11
  • Manually it is creating without problems. Also when I trying to use `createFile` instead of `createLink`, it works without errors and file successfully created. But how to create link programmatically? – BArtWell Apr 24 '23 at 18:12
  • I edited my answer with a java lib that features .lnk read/write. If you end up having problems even after using it, there is still a solution that calls VBScript, but mixing up too many programming languages may sound too odd for such a simple file creation problem. Hope you can manage it with java only! – Eduardo Poço Apr 24 '23 at 19:28
  • As I see it is not possible to include Java library mslinks to Kotlin Multiplatform Project. I've added `implementation(files("./libs/mslinks-1.1.0.jar"))` and it synchronized without problems. But Kotlin doesn't see any classes from this library (for example ShellLinkHelper is unresolved reference), – BArtWell Apr 25 '23 at 13:28
  • Oh, I see. I will update the answer with a vbscript code that creates the link. Your app just have to create the .vbs file and call the shell to run it. – Eduardo Poço Apr 25 '23 at 16:41