Is there a way to use or an alternative to InstallationManager.FindPackagesForCurrentPublisher? It looks like it is only for the phone.
I know you can launch an app by creating and then launching a URI, but I need to know if the app I want to launch is installed.
EDIT:
The app I want to launch is by the same publisher.
If we use the LaunchUriAsync(Uri) method to launch an app, system will firstly try to launch the installed app which registered this protocol, if the target app is not installed, then it will open the Store app and show the recommended apps which registered this protocol.
FindPackagesForCurrentPublisher method can only find the app packages with the same publisher ID as your app, for other app which is not with the same publisher, you will need to use FindPackages method, and this method requires ID_CAP_OEM_DEPLOYMENT. For desktop, there is no method now, you need special access to do that work, otherwise you can't break the sand box of UWP app.
But if your app won't be published into the Store, there is method which use PackageManager class to find the installed package. To use this class, you will need to add packageManagement capability into your app's manifest like this:
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
...
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="packageManagement" />
</Capabilities>
</Package>
For this capability, you can refer to Special and restricted capabilities.
At last you can use this class in your app, for example list all the installed packages:
var packageManager = new PackageManager();
IEnumerable<Windows.ApplicationModel.Package> packages = (IEnumerable<Windows.ApplicationModel.Package>)packageManager.FindPackagesForUser("");
var list = packages.ToList();
Related
I have a solution consisting of a Windows Application Packaging Project that groups two other projects:
A UWP project, named UwpUI, which is the entry point of the package. It can also be launched by protocol activation.
A .NET framework project, named FrameworkLogic, declared as Fulltrust.
An AppServiceConnection connects the two projects and allows a bi-directional communication between them.
It works using a well known pattern, described in this blog post by Stefan Wick:
Uwp with desktop extension-part 3
The package.appxmanifest (of my app) contains this.
<Extensions>
<desktop:Extension
Category="windows.fullTrustProcess"
Executable="FrameworkLogic\FrameworkLogic.exe">
</desktop:Extension>
<uap:Extension Category="windows.appService">
<uap:AppService Name="BidirectionalCom" />
</uap:Extension>
<uap:Extension Category="windows.protocol" Executable="UwpUI.exe"
EntryPoint="UwpUI.App">
<uap:Protocol Name="protoLaunch" />
</uap:Extension>
The uwp starts the fulltrust process like that:
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
In the entrypoint of the fulltrust .net framework, the connection is made with:
Connection = new AppServiceConnection();
Connection.AppServiceName = "BidirectionalCom";
var familyName = Package.Current.Id.FamilyName;
Connection.PackageFamilyName = familyName;
Connection.RequestReceived += Connection_RequestReceived;
Connection.ServiceClosed += Connection_ServiceClosed;
AppServiceConnectionStatus status = await Connection.OpenAsync();
opening the connection result in a call on the uwp side in the method
OnBackgroundActivated(BackgroundActivatedEventArgs args)
Where a reference to the connection is kept. Everything works.
The new requirement is this : set a console app (or a WPF app) as the package entry point.
If the package is launched without arguments, the new console app launches the uwp project by protocol activation. The bi-directional communication between the UWP and the .NET framework is instantiated and used.
If the app is launched with arguments (in my case, from the jumplist), then only the console app is used.
Adding the new project and setting it as the package entry point results in the following error:
DEP0700: Registration of the app failed. [0x80073CF6] AppxManifest.xml(44,10): error 0x80080204: Cannot register the package because the extension is missing an EntryPoint or StartPage attribute.
The solution on this SO post got me further.
Seems logical : the appservice must be defined under the project that uses it, which is not the package's entrypoint anymore.
My package manifest now include a second app (UwpUI) and looks like this:
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements DisplayName="Home" Description="Package" BackgroundColor="white" Square44x44Logo="Images\Square44x44Logo.png">
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.protocol" Executable="UwpUI.exe" EntryPoint="UwpUI.App" ><uap:Protocol Name="protoLaunch" />
</uap:Extension>
<desktop:Extension Category="windows.fullTrustProcess" Executable="FrameworkLogic\FrameworkLogic.exe">
</desktop:Extension>
</Extensions>
</Application>
<Application Id="App2" Executable="UwpUI.exe" EntryPoint="UwpUI.App">
<uap:VisualElements AppListEntry="none" DisplayName="Home" Description="Package" BackgroundColor="white" Square44x44Logo="Images\Square44x44Logo.png" Square150x150Logo="Images\Square150x150Logo.png">
<uap:DefaultTile ShortName="-TestApp-" Square71x71Logo="Images\SmallTile.png" Wide310x150Logo="Images\Wide310x150Logo.png" Square310x310Logo="Images\LargeTile.png"/>
<uap:SplashScreen BackgroundColor="white" Image="Images\SplashScreen.png" a:Optional="true"/>
</uap:VisualElements>
<Extensions>
<uap:Extension Category="windows.appService" >
<uap:AppService Name="BidirectionalCom" uap4:SupportsMultipleInstances="false"/>
</uap:Extension>
</Extensions>
</Application>
Doing that works as far as launching the fulltrust project, and establishing the connection, with a call to OnBackgroundActivated(BackgroundActivatedEventArgs args). There, I can succesfuly send a request and get an answer.
But I hit two major problems:
Any (static or instance) field or event instantiated in app.xaml.cs of the UwpUI project is null when it is called from another method, including the reference to the connection.
Prior to the modification, in debug mode at least, I could set breakpoints in both the UWP and the .NET framework project by doing 'detach all', then 'attach to process'. Now When attaching, the .NET framework project is greyed out.
Any idea what I'm missing? Problem 1 is the worse, since it breaks the app, but I need to solve the two.
Thank you.
EDIT : When looking at Task Manager, I see two processes with the same entry point (UwpUI.exe). Indeed, breakpoints show me that the call to the uwp constructor ( App.xaml.cs.App()), is called twice.
That certainly explains problem 1: fields are set in one instance and are of course null in the second instance.
Seems I need to structure my manifest differently, but I have yet to find how.
EDIT: Example project Here
Basically I'd like to give users the ability to add shortcuts to other apps installed on their PC to my app so that they can launch them from within my app. I'd like for them to be able to launch Win32 apps AND UWP apps (Windows 10 Store apps). My app is not a file explorer, but users will simply have the ability to launch their favorite apps from within my app. I have my reasons for wanting this type of feature implemented. -__-
Is there a way UWP apps from within my UWP app?
UWP has provide a way to query installed UWP app for current user. you could use FindPackagesForUser to get them. And then call GetAppListEntriesAsync to get app entry for each app. If you want launch the app, just call LaunchAsync method. For more please refer the following sample code.
private async void FindBtn_Click(object sender, RoutedEventArgs e)
{
PackageManager manager = new PackageManager();
var packages = manager.FindPackagesForUser(string.Empty);
foreach (var package in packages)
{
var appEntries = await package.GetAppListEntriesAsync();
var firstApp = appEntries.FirstOrDefault();
if (firstApp != null)
{
await firstApp?.LaunchAsync();
}
}
}
Please note
``
Before call FindPackagesForUser, you need enable packageQuery capability
<Package
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap" >
......
<rescap:Capability Name="packageQuery" />
Is there a way to launch external .exe files
Currently, UWP has not provide such api to launch win32 app with path directly like classical desktop app, if you do want this feature, we suggest you make desktop extension for your UWP app, and get installed app and launch it within extension part.
According to the docs I can just use this: Windows.ApplicationModel.AppDisplayInfo.DisplayName
But I get error: An object reference is required for the non-static field, method, or property 'AppDisplayInfo.DisplayName
I can't add 'AppDiagnostics' capability or use the Package Display name which seems to be the most common solutions for this. Is the documentation wrong or am I doing something wrong?
If someone needs it for the WinUI 3
Windows.ApplicationModel.Package.Current.DisplayName
If you just want the DisplayName of your current project, you can use the following code without the need to declare the appDiagnostics capability:
string displayName = Windows.ApplicationModel.AppInfo.Current.DisplayInfo.DisplayName;
If you want the DisplayName of all running apps including UWP apps, Win32 apps, system services and so on, you need to add the appDiagnostics capability in manifest first.
Check the steps to add the appDiagnostics capability:
Add xmlns:rescap in Package and add rescap in IgnorableNamespaces. Then, add the appDiagnostics capability in Capabilities.
<Package xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap">
<Capabilities>
<rescap:Capability Name="appDiagnostics" />
</Capabilities>
</Package>
The appDiagnostics capability is a restricted capability, you need to get the permission from users. A user-consent prompt will be triggered at the first time calling the diagnostic APIs such as AppDiagnosticInfo.RequestInfoAsync(). Or users can open Settings panel, find the Privacy option and set the App Diagnostics.
Note that if permission is denied by users, then the APIs will only return information about the current app.
Add the following code to view the DisplayName of all running apps.
var list = await AppDiagnosticInfo.RequestInfoAsync();
foreach (var info in list)
{
string name = info.AppInfo.DisplayInfo.DisplayName;
}
I am trying to integrate different files and links to the Cortana voice commands using C#. Most of the applications are working fine when i copy those particular files in the Cortana voice command application folder but i am unable to launch an *.exe file (copied in the same folder). The usual error i am getting is access denied even after launching VS as admin. I am attaching the code line along with the error screenshot.
{"Abrir NAV", (Action)(async () => {
StorageFile file = await Package.Current.InstalledLocation.GetFileAsync(#"Microsoft.Dynamics.Nav.Client.exe");
await Launcher.LaunchFileAsync(file);
})
},
Cortana Error
You could not launch executable file from your UWP app directly.
MSDN document has mentioned this point:
This API also imposes several restrictions on what types of files it can launch. Many file types that contain executable code, for example .exe, .msi, and .js files, are blocked from launching. This restriction protects users from potentially malicious files that could modify the system. From launcher documentation.
According to your description, your ".exe" file was contained in your UWP project. So, you could use the FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync() method to activate the full-trust Win32 component of an application from a Universal Windows app component in the same application package.
Please note the "full-trust" concept. You would need to declare "full-trust" for your ".exe" file in "Package.appxmanifest". For example:
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
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 desktop">
<Applications>
<Application>
...
<Extensions>
<desktop:Extension Category="windows.fullTrustProcess" Executable="MyFiles\ConsoleApp1.exe"/>
</Extensions>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
</Package>
Then, in code, you could call this method to launch that ".exe" file.
await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
The background task registration code looks like this:
var builder = new BackgroundTaskBuilder();
builder.Name = name;
builder.TaskEntryPoint = typeof(BackgroundTaskClass).FullName;
var trigger = new GattCharacteristicNotificationTrigger(characteristic);
builder.SetTrigger(trigger);
btr = builder.Register();
The entry in the manifest is:
<Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTaskNS.BackgroundTaskClass">
<BackgroundTasks>
<Task Type="deviceConnectionChange" />
<Task Type="bluetooth" />
</BackgroundTasks>
</Extension>
The Register() method triggers this error:
Access is denied.
Your App does not have permission to use the Gatt Service in the
background. Make sure you have declared the DeviceCapability and Task
Type 'bluetooth' in your manifest and that the application has been
granted access to this device.
This only happens on Creators Update installed on the build machine and also targeting the Creators Update SDK. This worked well before we updated the SDK and the build machine.
We've had the same issue with UWP app on windows 10 mobile.
We updated windows 10 mobile to build 10.0.15230.0, then deleted the app (manually on a phone) and installed it again. Now it works fine.
Also we installed last version of SDK, but I think this step can be skipped.
In the compatibility section of your manifest, add this:
<Capabilities>
<DeviceCapability Name="bluetooth" />
</Capabilities>
Didn't see it in your code sample. Could be that you need to call RequestAccessAsync from a UX thread on the GattDeviceService which contains the characteristic before registering your trigger.