1

We have a UWP app in the Windows Store. From this app we would like to launch various apps on the same system. For this process we need to do 2 things.

  1. Check if the app exists on the system
  2. If yes, launch it. If no, give feedback

We tried a couple of things but i'm searching for the best way to do this. We would like to launch both other UWP apps and Standalone apps.

I tried messing with the Unity PlayerPrefs, but that acts weird. It works if I make a custom PlayerPref and check if it exists from within 1 app, but as soon as I make a playerpref in the UWP and check for it in the Standalone I get nothing. And vice versa ofcourse. (Yes I know UWP saves its playerprefs somewhere else)

What would be the best general solution to this? Continue messing around with Playerprefs and search for different paths depending on the app we want to open?(Standalone, UWP) or some other way?

EDIT: What I have so far:

        if (Input.GetKeyDown(KeyCode.Backspace))
    {
        PlayerPrefs.SetString("42069" , "testing_this");
        PlayerPrefs.Save();
        Debug.Log("Wrote key 42069 to registry with: -value testing_this-");
    }

    if (Input.GetKeyDown(KeyCode.Space))
    {
        if (PlayerPrefs.HasKey("42069"))
        {
            Debug.Log("I found the key 42069 in my registry");
            cube.SetActive(true);
        }
        else
        {
            Debug.Log("I cant find key 42069 in my registry");
        }
    }

    if (Input.GetKeyDown(KeyCode.S))
    {
        const string registry_key = @"SOFTWARE\DefaultCompany";
        using(RegistryKey key = Registry.CurrentUser.OpenSubKey(registry_key))
        {
            if (key != null)
                foreach (string subKeyName in key.GetSubKeyNames())
                {
                    if (subKeyName == "RegistryTesting")
                    {
                        Debug.Log("I found the key on path: " + registry_key);
                    }
                }
        }
    }

EDIT: No one? I know there is a way. All I need to do is check whether a standalone app exists from a UWP app. But I do not have acces to the register in a UWP app. I know there are some ways with bridges etc, but I have no clue how and where to start.

Patrick
  • 135
  • 1
  • 14
  • 3
    Would be helpful if you can post what code you have so far so we can make recommendations. – slaphshot33324 Mar 11 '19 at 15:58
  • Right my bad. I added it. It's nothing much as I just started testing, but I can't really find a proper way to do this. Right now it works when I open a app, press backspace to create the key, and then press space to check if it exist. But it doesn't work if I then open up a UWP app with the same code and press space to check if it exist. – Patrick Mar 11 '19 at 16:01
  • Ok, I see what you're trying to do. I don't believe you can share Playerprefs across apps like that. I believe you are going to have to create your own mechanism such as writing and reading the Registry (i.e. set a registry key = 1 and then read that same registry key from the other app), write to a text file with a known location, read/write to a db that is accessible to both applications or something similar. – slaphshot33324 Mar 11 '19 at 17:16
  • I see. That sucks. I'll go on to do some more research myself, otherwise I'll have to find something else like you said. Thanks for the help. – Patrick Mar 12 '19 at 08:06
  • I did a bit more research as well, see post here https://stackoverflow.com/questions/48899692/how-to-access-registry-key-in-a-uwp-app If this is the case it looks like your best bet is to read/write from a db that both apps have access to. – slaphshot33324 Mar 12 '19 at 14:15
  • I saw that post indeed. Didn't help me much further. I'm a bit of a noob regarding all this. All I ever did was simple C# programming so I have little to no knowledge about other stuff. Currently i'm messing around with urischemes. Not sure if they're what i'm looking for. – Patrick Mar 12 '19 at 14:32
  • I think you will find that a uri is also only local to the app and cannot cross app boundaries. Do your apps have access to the internet? If that is the case then the suggestion would be to build a webservice on a server and when you install an app send the unique identifier of the user and the app to the webservice to mark it installed and build a webservice that can check for a particular unique identifier of a user to see if an app has been installed. – slaphshot33324 Mar 12 '19 at 15:34

1 Answers1

0

I encountered a somewhat similar situation but I was checking to see if the app was running and if not, start it. In my situation, the app I wanted to check and launch was not something I wrote nor was it UWP so my solution may not work for you as the capabilities to do so are restricted.

First adding restricted capabilities to the package.appxmanifest (code).

xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap"

Then adding "appDiagnostics" capability to the app.

<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="appDiagnostics" />
</Capabilities>

Now you have the ability to request permission to access running processes and check.

using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.System;
using Windows.System.Diagnostics;
class ProcessChecker
{
public static async Task<bool> CheckForRunningProcess(string processName)
    {
        //Requests permission for app.
        await AppDiagnosticInfo.RequestAccessAsync();
        //Gets the running processes.
        var processes = ProcessDiagnosticInfo.GetForProcesses();
        //Returns result of searching for process name.
        return processes.Any(processDiagnosticInfo => processDiagnosticInfo.ExecutableFileName.Contains(processName));
    }
}

Launching a non UWP app/process is a bit dirty but possible.

First, a simple console (non uwp) app is needed. Replace the directoryPath in the code below with your applicable directory path.

using System;
using System.Diagnostics;

namespace Launcher
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                if (args.Length != 3) return;
                string executable = args[2];
                string directoryPath = "C:\\Program Files (x86)\\Arduino\\hardware\\tools\\";
                Process.Start(directoryPath + executable);
            }
            catch (Exception e)
            {
                Console.ReadLine();
            }

        }
    }
}

Build the console app and place the Launcher.exe in your UWP app asset folder.

Now you need to add the capability to run the Launcher and to do so, add "runFullTrust" capability to the UWP app.

<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="appDiagnostics" />
</Capabilities>

For desktop, you also need to add desktop capabilities and extension to the package.appxmanifest (code).

xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
IgnorableNamespaces="uap mp rescap"

Then further below in the package.appxManifest and inside .

<Extensions>
    <desktop:Extension Category="windows.fullTrustProcess" Executable="Assets\Launcher.exe" >
      <desktop:FullTrustProcess>
        <desktop:ParameterGroup GroupId="SomeGroup1" Parameters="ProcessName1.exe"/>
        <desktop:ParameterGroup GroupId="SomeGroup2" Parameters="ProcessName2.exe"/>
      </desktop:FullTrustProcess>
    </desktop:Extension>
</Extensions>

Finally, add the "Windows Desktop Extensions for the UWP" references needed for your app versions.

Now you can call your Launcher and start the necessary process.

public static async void LaunchProcess(int groupId)
    {
        switch (groupId)
        {
            case 1:
                await FullTrustProcessLauncher.LaunchFullTrustProcessForAppAsync("SomeGroup1");
                break;
            case 2:
                await FullTrustProcessLauncher.LaunchFullTrustProcessForAppAsync("SomeGroup2");
                break;
        }
    }

Combining the above, one possibility may be...

    public enum ProcessResult
        {
            ProcessAlreadyRunning,
            FailedToLaunch,
            SuccessfulLaunch
        }
    public static async Task<ProcessResult> CheckLaunchCheckProcess1()
        {
            if (await CheckForRunningProcess("ProcessName1.exe")) return ProcessResult.ProcessAlreadyRunning;
            LaunchProcess(1);
            return await CheckForRunningProcess("ProcessName1.exe") ? ProcessResult.SuccessfulLaunch : ProcessResult.FailedToLaunch;
        }

This is just an example of how to accomplish launching non uwp apps within a single uwp app. For a windows store app submissions, restricted capabilities require approval and can delay or halt deployment if denied.

If the both the calling app and launching app are uwp and written by you, the appropriate solution may be using URI for app to app communication, MS doc link Launch an app with a URI