Hello! How to handle “Open With” feature with UWP? I want to open an image file if it was selected as “Open With” target.
Environment.GetCommandLineArgs() and UnityEngine.WSA.Application.arguments doesn’t contain a path.
I’ve found that Application.OnFileActivated is invoked when the application is activated through file-open:
But how can I access this callback in Unity?
Please note that .NET scriptng backend is no longer available, so it looks we have to deal with C++ (I don’t know it btw).
A few years later…
I was able to implement “Open With” feature in UWP app (sometimes called ‘launched via file’).
- Build XAML project and open App.xaml.cpp, navigate to
App::OnFileActivated
- You’ll see there how Unity devs translates file paths to Unity app with “File=” prefix. You’ll be able to receive them later with
UnityEngine.WSA.Application.arguments, but this will be useless because the app doesn’t have access to random paths (except predefined locations defined in Capabilities)
- Now we need to modify
App::OnFileActivated. The main idea is to use StorageApplicationPermissions.FutureAccessList and pass file tokens to our Unity app instead of file paths. This will “keep” access to files (not regular files as you can expect, but StorageFile instances). Let’s make 2 changes to App::OnFileActivated. Change our prefix String^ appArgs = "FileTokens="; and call FutureAccessList to receive file tokens: appArgs += Windows::Storage::AccessCache::StorageApplicationPermissions::FutureAccessList->Add(file);
- Now we can return to Unity and get tokens from
UnityEngine.WSA.Application.arguments
- Finally, we can read StorageFile (note, this code should be hidden with #if UNITY_WSA && !UNITY_EDITOR. Unfortunately, this operation is async, so we’ll have to create and run Task, and wait for result.
public static async Task<object[]> ReadStorageFileAsync(string token)
{
var file = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(token);
var buffer = await Windows.Storage.FileIO.ReadBufferAsync(file);
using var reader = Windows.Storage.Streams.DataReader.FromBuffer(buffer);
var bytes = new byte[buffer.Length];
reader.ReadBytes(bytes);
return new object[] { bytes, file.Path };
}