Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How to access Application.OnFileActivated if the app was launched as "Open With" for an image?

Discussion in 'Windows' started by hippogames, Oct 12, 2021.

  1. hippogames

    hippogames

    Joined:
    Feb 5, 2015
    Posts:
    232
    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:
    https://docs.microsoft.com/en-us/uw....application.onfileactivated?view=winrt-22000

    But how can I access this callback in Unity?
     
  2. hippogames

    hippogames

    Joined:
    Feb 5, 2015
    Posts:
    232
    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).
     
  3. hippogames

    hippogames

    Joined:
    Feb 5, 2015
    Posts:
    232
    A few years later...

    I was able to implement "Open With" feature in UWP app (sometimes called 'launched via file').

    1) Build XAML project and open App.xaml.cpp, navigate to
    App::OnFileActivated

    2) 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)
    3) 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);

    4) Now we can return to Unity and get tokens from
    UnityEngine.WSA.Application.arguments

    5) 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.
    Code (CSharp):
    1. public static async Task<object[]> ReadStorageFileAsync(string token)
    2. {
    3.     var file = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(token);
    4.     var buffer = await Windows.Storage.FileIO.ReadBufferAsync(file);
    5.     using var reader = Windows.Storage.Streams.DataReader.FromBuffer(buffer);
    6.     var bytes = new byte[buffer.Length];
    7.  
    8.     reader.ReadBytes(bytes);
    9.  
    10.     return new object[] { bytes, file.Path };
    11. }
     

    Attached Files:

    Last edited: Jan 15, 2023