C#中的IApplicationActivationManager::ActivateApplication是什么?

23
我正在为Metro应用程序进行自动化测试,我找到了一些需要的代码,但它是用C++编写的:http://blogs.msdn.com/b/windowsappdev/archive/2012/09/04/automating-the-testing-of-windows-8-apps.aspx 我的问题是,如何在C#中使用IApplicationActivationManager::ActivateApplication,因为我不会C++? 该方法的详细信息可以在这里找到:http://msdn.microsoft.com/en-us/library/windows/desktop/hh706903(v=vs.85).aspx 这里是我从Shobjidl.idl中提取的代码:
cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(ACTIVATEOPTIONS)")

// IApplicationActivationManger is used to activate an immersive application identified by its Application User Model Id.
//
// Developers who are interested in using the Application Activation Manager do not need to implement the following
// interface. An implementation is provided through the CoCreatable Object with CLSID_ApplicationActivationManager.
[
    object,
    uuid(2e941141-7f97-4756-ba1d-9decde894a3d),
    pointer_default(unique)
]
interface IApplicationActivationManager : IUnknown
{
    // 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.
    HRESULT ActivateApplication(
        [in] LPCWSTR appUserModelId,
        [in, unique] LPCWSTR arguments,
        [in] ACTIVATEOPTIONS options,
        [out] DWORD *processId);
    HRESULT ActivateForFile(
        [in] LPCWSTR appUserModelId,
        [in] IShellItemArray *itemArray,
        [in, unique] LPCWSTR verb,
        [out] DWORD *processId);
    HRESULT ActivateForProtocol(
        [in] LPCWSTR appUserModelId,
        [in] IShellItemArray *itemArray,
        [out] DWORD *processId);
}



// CLSID_ApplicationActivationManager
    [ uuid(45BA127D-10A8-46EA-8AB7-56EA9078943C) ] coclass ApplicationActivationManager { interface IApplicationActivationManager; }
任何想法吗? 谢谢。

1
它们实际上是相同的;你只需要将接口声明翻译成C#即可。 - James McNellis
2个回答

34

试用下面的代码片段,它对我有效。

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
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);
}


class Program
{
    static void Main(string[] args)
    {
        ApplicationActivationManager appActiveManager = new ApplicationActivationManager();//Class not registered
        uint pid;
        appActiveManager.ActivateApplication("2c123c17-8b21-4eb8-8b7f-fdc35c8b7718_n2533ggrncqjt!App", null, ActivateOptions.None, out pid);
        Console.WriteLine();
        Console.ReadLine();
    }
}
希望你已经知道如何获取应用程序名称以激活。然而,我想在这里分享这个信息,给那些可能搜索相同内容的人。我们可以从下面的注册表位置获得 AppUserModelID: Windows Registry Editor

7
这是sankar答案的更新版本(非常感谢他,真的帮了我很多),针对ActivateForFile方法。我将itemArray更改为IShellItemArray而不是IntPtr,并添加了来自shell32的接口和方法。
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] [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] /*IShellItemArray* */ 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
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] [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)]  /*IShellItemArray* */ 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);
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
interface IShellItem
{
}

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("b63ea76d-1f85-456f-a19c-48159efa858b")]
interface IShellItemArray
{
}

internal class Program2
{
    [DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
    private static extern void SHCreateItemFromParsingName(
        [In] [MarshalAs(UnmanagedType.LPWStr)] string pszPath,
        [In] IntPtr pbc,
        [In] [MarshalAs(UnmanagedType.LPStruct)] Guid iIdIShellItem,
        [Out] [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] out IShellItem iShellItem);

    [DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
    private static extern void SHCreateShellItemArrayFromShellItem(
        [In] [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] IShellItem psi,
        [In] [MarshalAs(UnmanagedType.LPStruct)] Guid iIdIShellItem,
        [Out] [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] out IShellItemArray iShellItemArray);

    private static void Main(string[] args)
    {
        ApplicationActivationManager appActiveManager = new ApplicationActivationManager();//Class not registered
        uint pid;
        appActiveManager.ActivateApplication("2c123c17-8b21-4eb8-8b7f-fdc35c8b7718_n2533ggrncqjt!App", null, ActivateOptions.None, out pid);
        Console.WriteLine("Activated");
        Console.ReadLine();

        IShellItemArray array = GetShellItemArray(@"C:\temp\somefile.xyz");
        appActiveManager.ActivateForFile("2c123c17-8b21-4eb8-8b7f-fdc35c8b7718_n2533ggrncqjt!App", array, "Open",
            out pid);
        Console.WriteLine("Activated for file");
        Console.ReadLine();
    }

    private static IShellItemArray GetShellItemArray(string sourceFile)
    {
        IShellItem item = GetShellItem(sourceFile);
        IShellItemArray array = GetShellItemArray(item);

        return array;
    }

    private static IShellItem GetShellItem(string sourceFile)
    {
        IShellItem iShellItem = null;
        Guid iIdIShellItem = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
        SHCreateItemFromParsingName(sourceFile, IntPtr.Zero, iIdIShellItem, out iShellItem);

        return iShellItem;
    }

    private static IShellItemArray GetShellItemArray(IShellItem shellItem)
    {
        IShellItemArray iShellItemArray = null;
        Guid iIdIShellItemArray = new Guid("b63ea76d-1f85-456f-a19c-48159efa858b");
        SHCreateShellItemArrayFromShellItem(shellItem, iIdIShellItemArray, out iShellItemArray);

        return iShellItemArray;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接