IApplicationActivationManager在Delphi中的用法示例

huangapple go评论76阅读模式
英文:

IApplicationActivationManager usage example in Delphi

问题

我已经进行了大量搜索,但没有找到在Delphi中使用Windows IApplicationActivationManager 的示例。在我的Delphi 10.4.2社区版中似乎没有定义这个接口。我需要加载Windows应用商店应用程序并等待它们终止。

有没有人在Delphi中使用过这个接口,可以提供如何定义和使用它的示例?

我在这个网站上找到了以下C#示例,但在寻找一个可用的Delphi等效示例方面一直不成功:

IApplicationActivationManager::ActivateApplication in C#?

我尝试使用CreateProcessShellExecuteexplorer.exe等方法调用Windows应用商店应用程序(带有AUMID的打包应用程序),但没有一个能满足我的需求。传统应用程序运行良好。通过CreateProcessShellExecuteexplorer.exe等方式启动的进程都会在被调用的应用程序本身终止之前终止并返回到我的应用程序。我需要我的应用程序等待被调用的应用程序本身终止。

在我的应用程序中,我需要:

  1. 执行一些可配置的操作(例如:从Zip文件中提取文件,解密文件等)。
  2. 运行与步骤1中生成的文件相关的可配置应用程序(例如:编辑文件)。
  3. 对步骤1中的操作执行镜像/撤销操作(例如:将更新的文件添加回Zip文件,重新加密文件等)。

IApplicationActivationManager接口似乎可以满足我的应用程序需求,因为它返回一个ProcessID,可能是启动的应用程序的ID。然后,我可以监视该ProcessID并等待应用程序终止。

英文:

I've done a lot of searching, but have not found any examples using the Windows IApplicationActivationManager in Delphi. The interface does not appear to be defined in my Delphi 10.4.2 Community Edition. I need to load Windows AppStore application and wait for them to terminate.

Has anybody used this interface in Delphi, and can provide an example of how to define and use it?

I've found the following on this site using C#, but have been unsuccessful in coming up with a working Delphi equivalent:

IApplicationActivationManager::ActivateApplication in C#?

I have tried using CreateProcess, ShellExecute, explorer.exe, etc invocations with Windows AppStore application (packaged apps with AUMID), but nothing works as needed. Traditional apps work fine. Invoking a process via CreateProcess, ShellExecute, explorer.exe etc all terminate and return to my application before the invoked application itself terminates. I need my application to wait until the invoked application itself terminates.

In my application, I need to:

  1. perform some configurable action (eg: extract a file from a Zip file, decrypt a file, etc).
  2. run a configurable application appropriate to the resulting file in step 1 (eg: edit the file).
  3. perform a mirror/undo action to the action in step 1 (eg: add updated file back into the Zip file, re-encrypt the file, etc).

The IApplicationActivationManager interface appears to do what I need for my application, as it returns a ProcessID, presumably for the application that it started. I can then monitor that ProcessID and wait for the application to terminate.

答案1

得分: 1

以下是您要翻译的内容:

Has anybody used this interface in Delphi, and can provide an example of how to define and use it?

有人在Delphi中使用过这个接口吗,可以提供如何定义和使用它的示例吗?

Try something like this:

尝试类似以下的代码:

uses
  ..., System.Win.ComObj, Winapi.ShlObj;

type
  ActivateOptions = (
    None = 0,
    DesignMode = 1,
    NoErrorUI = 2,
    NoSplashScreen = 4
  );

  IApplicationActivationManager = interface(IInterface)
    ['{2e941141-7f97-4756-ba1d-9decde894a3d}']
    function ActivateApplication(appUserModelId: PWideChar; arguments: PWideChar; options: ActivateOptions; out processId: DWORD): HResult; stdcall;
    function ActivateForFile(appUserModelId: PWideChar; itemArray: IShellItemArray; verb: PWideChar; out processId: DWORD): HResult; stdcall;
    function ActivateForProtocol(appUserModelId: PWideChar; itemArray: IShellItemArray; out processId: DWORD): HResult; stdcall;
  end;

const
  CLSID_ApplicationActivationManager: TGUID = '{45BA127D-10A8-46EA-8AB7-56EA9078943C}';

...

var
  appMgr: IApplicationActivationManager;
  pid: DWORD;
begin
  appMgr := CreateComObject(CLSID_ApplicationActivationManager) as IApplicationActivationManager;
  // alternatively:
  // OleCheck(CoCreateInstance(CLSID_ApplicationActivationManager, nil, CLSCTX_LOCAL_SERVER, IApplicationActivationManager, appMgr));

  OleCheck(appMgr.ActivateApplication('AppIdHere', nil, ActivateOptions.None, pid)); 

  // use pid to wait on process as needed...
end;

Traditional apps work fine. Invoking a process via CreateProcess, ShellExecute, explorer.exe etc all terminate and return to my application before the invoked application itself terminates. I need my application to wait until the invoked application itself terminates.

传统应用程序运行正常。通过CreateProcessShellExecuteexplorer.exe等调用进程都会在调用的应用程序本身终止之前终止并返回到我的应用程序。我需要等待我的应用程序,直到调用的应用程序本身终止。

CreateProcess() 返回一个进程句柄,您可以使用 WaitForSingleObject() 或类似的函数来等待它。ShellExecuteEx() 如果指定了 SEE_MASK_NOCLOSEPROCESS 标志,也可以返回类似的进程句柄。

The IApplicationActivationManager interface appears to do what I need for my application, as it returns a ProcessID, presumably for the application that it started. I can then monitor that ProcessID and wait for the application to terminate.

IApplicationActivationManager 接口似乎满足了我应用程序的需求,因为它返回一个进程ID,应该是启动的应用程序的进程ID。然后,我可以监视该进程ID并等待应用程序终止。

英文:

> Has anybody used this interface in Delphi, and can provide an example of how to define and use it?

Try something like this:

uses
  ..., System.Win.ComObj, Winapi.ShlObj;

type
  ActivateOptions = (
    None = 0,
    DesignMode = 1,
    NoErrorUI = 2,
    NoSplashScreen = 4
  );

  IApplicationActivationManager = interface(IInterface)
    ['{2e941141-7f97-4756-ba1d-9decde894a3d}']
    function ActivateApplication(appUserModelId: PWideChar; arguments: PWideChar; options: ActivateOptions; out processId: DWORD): HResult; stdcall;
    function ActivateForFile(appUserModelId: PWideChar; itemArray: IShellItemArray; verb: PWideChar; out processId: DWORD): HResult; stdcall;
    function ActivateForProtocol(appUserModelId: PWideChar; itemArray: IShellItemArray; out processId: DWORD): HResult; stdcall;
  end;

const
  CLSID_ApplicationActivationManager: TGUID = '{45BA127D-10A8-46EA-8AB7-56EA9078943C}';

...

var
  appMgr: IApplicationActivationManager;
  pid: DWORD;
begin
  appMgr := CreateComObject(CLSID_ApplicationActivationManager) as IApplicationActivationManager;
  // alternatively:
  // OleCheck(CoCreateInstance(CLSID_ApplicationActivationManager, nil, CLSCTX_LOCAL_SERVER, IApplicationActivationManager, appMgr));

  OleCheck(appMgr.ActivateApplication('AppIdHere', nil, ActivateOptions.None, pid)); 

  // use pid to wait on process as needed...
end;

> Traditional apps work fine. Invoking a process via CreateProcess, ShellExecute, explorer.exe etc all terminate and return to my application before the invoked application itself terminates. I need my application to wait until the invoked application itself terminates.

CreateProcess() returns a process HANDLE which you can wait on, such as with WaitForSingleObject() or equivalent. ShellExecuteEx() can return a similar HANDLE if you specify the SEE_MASK_NOCLOSEPROCESS flag.

> The IApplicationActivationManager interface appears to do what I need for my application, as it returns a ProcessID, presumably for the application that it started. I can then monitor that ProcessID and wait for the application to terminate.

You can pass the returned ProcessID to OpenProcess() to get a HANDLE that you can then wait on.

huangapple
  • 本文由 发表于 2023年3月7日 04:55:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75655769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定