23

我正在为 Metro 应用程序进行自动化测试,我发现代码可以做很多我需要的事情,但它是用 C++ 编写的:http: //blogs.msdn.com/b/windowsappdev/archive/2012/09/04/ 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; }

有任何想法吗?

谢谢

4

2 回答 2

33

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

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 注册表编辑器

于 2012-10-17T04:48:59.257 回答
7

这是 ActivateForFile 方法的 sankar 答案的更新版本(感谢那个,真的帮助了我)。我将 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;
    }
于 2015-03-19T13:36:02.970 回答