# encoding: ascii
# api: csharp
# title: MetroApps Module
# description: This module provides two functions:
# version: 1.0
# type: module
# author: Tome Tanasovski
# license: CC0
# function: Get-MetroApp
# x-poshcode-id: 3740
# x-archived: 2017-03-14T17:40:17
# x-published: 2013-11-02T20:39:00
#
# Get-MetroApp – This cmdlet reads the registry for the keys that have the launcher id and the entry point (interesting for xaml apps, but not so much for html5 apps)
# Start-MetroApp – This cmdlet uses one of the ids returned by Get-metroapp to launch an app in the win8 metro interface
#
<#
Created by: Tome Tanasovski
Version: 1.0
Date: 11/2/2012
This module provides two functions:
Get-MetroApp - This cmdlet reads the registry for the keys that have the launcher id and the entry point (interesting for xaml apps, but not so much for html5 apps)
Start-MetroApp - This cmdlet uses one of the ids returned by Get-metroapp to launch an app in the win8 metro interface
Apologies for the lack of get-help documentation, but I'll be doing a blog post about this shortly:
http://powertoe.wordpress.com
Original C# code modified slightly from here - also the registry info is on this page too:
http://stackoverflow.com/questions/12925748/iapplicationactivationmanageractivateapplication-in-c
#>
$code = @"
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Win8 {
public enum ActivateOptions
{
None = 0x00000000, // No flags set
DesignMode = 0x00000001, // The application is being activated for design mode, and thus will not be able to
// to create an immersive window. Window creation must be done by design tools which
// load the necessary components by communicating with a designer-specified service on
// the site chain established on the activation manager. The splash screen normally
// shown when an application is activated will also not appear. Most activations
// will not use this flag.
NoErrorUI = 0x00000002, // Do not show an error dialog if the app fails to activate.
NoSplashScreen = 0x00000004, // Do not show the splash screen when activating the app.
}
[ComImport, Guid("2e941141-7f97-4756-ba1d-9decde894a3d"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IApplicationActivationManager
{
// Activates the specified immersive application for the "Launch" contract, passing the provided arguments
// string into the application. Callers can obtain the process Id of the application instance fulfilling this contract.
IntPtr ActivateApplication([In] String appUserModelId, [In] String arguments, [In] ActivateOptions options, [Out] out UInt32 processId);
IntPtr ActivateForFile([In] String appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] String verb, [Out] out UInt32 processId);
IntPtr ActivateForProtocol([In] String appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out UInt32 processId);
}
[ComImport, Guid("45BA127D-10A8-46EA-8AB7-56EA9078943C")]//Application Activation Manager
public class ApplicationActivationManager : IApplicationActivationManager
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)/*, PreserveSig*/]
public extern IntPtr ActivateApplication([In] String appUserModelId, [In] String arguments, [In] ActivateOptions options, [Out] out UInt32 processId);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern IntPtr ActivateForFile([In] String appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] String verb, [Out] out UInt32 processId);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public extern IntPtr ActivateForProtocol([In] String appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out UInt32 processId);
}
}
"@
add-type -TypeDefinition $code
$appman = new-object Win8.ApplicationActivationManager
function Get-MetroApp {
$entry = 'HKCU:\Software\Classes\ActivatableClasses\Package'
foreach ($appkey in (dir $entry |select -ExpandProperty pspath)) {
#$id = ((dir (join-path $appkey 'Server')) |Get-ItemProperty).appusermodelid
$id = (dir (Join-Path $appkey server) |?{$_.pspath -notmatch 'BackgroundTransferHost.1'} |Get-ItemProperty).appusermodelid
if ($id) {
$possibleclassidkeys = dir (join-path $appkey 'ActivatableClassID') |select -ExpandProperty pspath
# we look for the app key first, then app.wwa, and then any other key if neither returns an entrypoint
$key = $possibleclassidkeys |?{$_ -match 'app$'}
$entrypoint=$null
if ($key) {
if (Test-Path (join-path $key CustomAttributes)) {
$entrypoint = (Get-ItemProperty (join-path $key CustomAttributes)).('appobject.entrypoint')
}
}
if (!$entrypoint) {
$key = $possibleclassidkeys |?{$_ -match 'app.wwa$'}
if ($key) {
if (Test-Path (join-path $key CustomAttributes)) {
$entrypoint = (Get-ItemProperty (join-path $key CustomAttributes)).('appobject.entrypoint')
}
}
}
if (!$entrypoint) {
foreach ($key in $possibleclassidkeys) {
if (Test-Path (join-path $key CustomAttributes)) {
$entrypoint = (Get-ItemProperty (join-path $key CustomAttributes)).('appobject.entrypoint')
break
}
}
}
new-object psobject -Property ([ordered] @{
EntryPoint = $entrypoint
ID = $id
})
}
}
}
function Start-MetroApp {
param(
[Parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$true)]
[string] $ID
)
$appman.ActivateApplication($ID,$null,[Win8.ActivateOptions]::None,[ref]0)
}