|
Delphi Programming / Object Pascal
[掲載 2021年10月08日] [更新 2021年10月11日] Delphi サンプルプログラム集 |
324_特定の UWP アプリが起動中かを確認 |
動作確認等 |
Windows 10 ビルド 19042 + Delphi XE5(UP2) Pro VCL-32 |
|
324_CheckRun_UWPApp.zip [4.3 MB] 2021年10月11日版 (EXE 同梱) |
デスクトップアプリでは,FindWindow 関数を使用して,ウィンドウのクラス名で目的のアプリのウィンドウが起動しているこを確認できます.Windows 10 の UWP アプリではこの方法は利用できません.Windows 10 の UWP アプリのウィンドウのクラス名は全て同じです.クラス名ではアプリを判定できません.
下に示すコードは,ウィンドウのタイトルでアプリを判定する例です.ペイント 3D を起動して [起動チェック] ボタンをクリックするとペイント 3D アプリが起動ていることが確認できます.ところが,ペイント 3D アプリを終了しても起動中になることがあります.Windows 10 の UWP アプリにはバックグラウンドで実行する機能があり,デスクトップに表示しているウィンドウを閉じても,バックグラウンドでそのアプリが実行されることがあります.その結果,次回の起動が) か高速にります (正確には,既に起動してバックグラウンドで実行されているのですが).このように,Windows 10 の UWP アプリは「親切」な仕様になっています. |
|
図1
ペイント 3D が実行中かを確認
- ウィンドウのタイトルで判定
- ペイント 3D を閉じてもこの結果となる
|
リスト1
ウィンドウのタイトルで,アプリが実行中かを判定するコード |
//=============================================================================
// 特定の UWP アプリが起動しているかを確認
// FindWindow 関数でウィンドウのタイトルを検索する方法
// デスクトップ画面に表示されていなくても「起動中」になることがある
// これは正確には正しい
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LTargetWnd : HWND;
LWndTitle : string;
LText : string;
begin
LWndTitle := 'タイトルなし ' + #$200E + '- ペイント 3D';
// 以下でもバックグラウンドて実行されている場合,結果は同じ
// LWndTitle := 'ペイント 3D';
LTargetWnd := FindWindow(nil, PChar(LWndTitle));
if LTargetWnd <> 0 then begin
LText := 'ペイント 3D は起動しています。';
MessageBox(Handle, PChar(LText), '情報', MB_TOPMOST or MB_ICONINFORMATION);
end else begin
LText := 'ペイント 3D は起動していません。';
MessageBox(Handle, PChar(LText), '情報', MB_TOPMOST or MB_ICONINFORMATION);
end;
end;
[備考 1]
Windows 10 の UWP アプリは,バックグラウンドで起動して実行されるのですから,このサンプルでは起動中のアプリの検出ができているわけです.本ページの主題は,正確に言うと「起動してウインドウがデスクトップに表示されている UWP アプリ」の確認です. |
[備考 2]
ペイント 3D のウィンドウのタイトルには Shift_JIS にはないコードポイントがありますが,これはアプリによって異なります.Chromium 版の Microsoft Edge では #$200B です. |
[備考 3]
ペイント 3D は,2017年10月17日の Windows 10 Fall Creators Update で搭載されたアプリです.初期の Windows 10 にはありません. |
01_特定の AppUserModelId の UWP アプリが起動中かを確認 |
デスクトップのアプリケーションを識別するのは EXE 名です.Windows 10 の UWP アプリを識別するのは,アプリケーション識別子である AppUserModelId の値です.この AppUserModelId の値を使用すると,特定の UWP アプリが起動していかを調べることが可能です.
このサンプルでは,EnumWindows 関数の引数に AppUserModelId の値を渡します.EnumWindows のコールバック関数内では,ウィンドウハンドルから AppUserModelId の値を取得して,引数の値と一致したら,引数にそのウインドウのハンドルの値を文字列にして返します.このウィンドウハンドルは,対象のアプリの操作に利用できます.
コールバック関数内では,DwmGetWindowAttribute 関数を使用して,待機中またはバックグラウンドで実行されているウィンドウを検索の対象外としています.
このサンプルは UWP アプリ専用です.特定の EXE 名のアプリが起動しているを確認する方法については,以下の最後のリンクの記事を参考にしてください. |
|
図2
起動中の場合
|
リスト2
特定の AppUserModelId の UWP アプリが起動中かを確認 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function EnumWindowProc(hWindow: HWND; lPara: LPARAM): Boolean; stdcall;
function GetWindowClassName(hWindow: HWND): string;
var
Form1: TForm1;
implementation
uses
Winapi.Dwmapi,
Winapi.ShellAPI,
Winapi.ActiveX,
Winapi.propSys,
Winapi.PropKey;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// テスト用の AppUserModelId の値をセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
// ペイント 3D
Edit1.Text:= 'Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint';
end;
//=============================================================================
// 特定の AppUserModelId の UWP アプリが起動しているかを確認
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LAppId : string;
LArgWnd : string;
LTargetWnd : HWND;
LText : string;
begin
LAppId := Trim(Edit1.Text);
LArgWnd := LAppId;
EnumWindows(@EnumWindowProc, LPARAM(@LArgWnd));
LTargetWnd := StrToIntDef(LArgWnd, 0);
if LTargetWnd <> 0 then begin
LText := 'ペイント 3D は起動しています。';
MessageBox(Handle, PChar(LText), '情報', MB_TOPMOST or MB_ICONINFORMATION);
end else begin
LText := 'ペイント 3D は起動していません。';
MessageBox(Handle, PChar(LText), '情報', MB_TOPMOST or MB_ICONINFORMATION);
end;
end;
//=============================================================================
// アプリを起動
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LShellPath : string;
begin
LShellPath := 'shell:AppsFolder\' + Trim(Edit1.Text);
ShellExecute(0, '', PChar(LShellPath), nil, nil, SW_SHOW);
end;
//-----------------------------------------------------------------------------
// EnumWindows のコールバック関数
// 引数 (lPara - AppUserModelId の値) と同じ UWP アプリが起動しているかをチェック
// 検出したら引数 (lPara) にそのウィンドウハンドルの値を文字列にして渡す
//-----------------------------------------------------------------------------
function EnumWindowProc(hWindow: HWND; lPara: LPARAM): Boolean; stdcall;
const
UWP_FRAMEWND = 'ApplicationFrameWindow';
DWMWA_CLOAKED = 14;
var
LIsUWPApp : Boolean;
LCloaked : BOOL;
LPropStore : IPropertyStore;
LPropVar : TPropVariant;
LAppID : string;
begin
Result := True;
if GetWindow(hWindow, GW_OWNER) <> 0 then exit;
if not IsWindowVisible(hWindow) then exit;
// 待機中またはバックグラウンドのウィンドウは対象外
DwmGetWindowAttribute(hWindow, DWMWA_CLOAKED, @LCloaked, SizeOf(LCloaked));
if LCloaked then Exit;
// クラス名 ApplicationFrameWindow のウインドウが UWP アプリ
LIsUWPApp := GetWindowClassName(hWindow) = UWP_FRAMEWND;
if LIsUWPApp then begin
// ウィンドウハンドルの値から AppUserModelId の値を取得
if SHGetPropertyStoreForWindow(hWindow,
IID_IPropertyStore,
Pointer(LPropStore)) <> S_OK then Exit;
if LPropStore.GetValue(PKEY_AppUserModel_ID, LPropVar) <> S_OK then Exit;
LAppID := LPropVar.bstrVal;
if SameText(LAppID, PString(lPara)^) then begin
PString(lPara)^ := IntToStr(hWindow);
Result := False;
end;
end;
end;
//-----------------------------------------------------------------------------
// ウィンドウのクラス名を取得する関数
//-----------------------------------------------------------------------------
function GetWindowClassName(hWindow: HWND): string;
var
LBuff : array [0..MAX_PATH - 1] of Char;
begin
Result := '';
FillChar(LBuff, SizeOf(LBuff), #0);
if (GetClassName(hWindow, @LBuff, MAX_PATH) > 0) then begin
Result := LBuff;
end;
end;
end.
上のサンプルでは,ペイント 3D のウィンドウハンドルを取得しいます.したがって,以下のコードを実行すれば,ペイント 3D のウィンドウの表示位置とサイズを変更できます. |
SetWindowPos(LTargetWnd,
0,
200, // 右端 X 座標
0, // 上端 Y 座標
500, // 幅
600, // 高さ
SWP_NOZORDER);
02_プロセスのハンドルと GetAppUserModelId 関数 |
Windows API には,起動中のプロセスのハンドルから AppUserModelId の値やパッケージ名を取得する関数類があります.例えば以下のような関数です.本サンプルは,GetApplicationUserModelId 関数を使用して,起動中の UWP アプリを判定する例です. |
// 以下の関数類におけるプロセスのハンドルとは
// クラス名が Windows.UI.Core.CoreWindow のウィンドウのプロセスハンドル
// プロセスのハンドルから AppUserModelId の値を取得
function GetApplicationUserModelId(hProcess: THandle; Size: PDWORD;
AppId: PWideChar): DWORD; stdcall; external 'kernelBase.dll';
// プロセスのハンドルからパッケージ名 (フルパッケージ名) 値を取得
// バージョン番号があるパッケージ名
function GetPackageFullName(hProcess: THANDLE; Size: PDWORD; Path: PWideChar):
DWORD; stdcall; external 'kernel32.dll';
// プロセスのハンドルからパッケージのファミリー名を取得
// これをパッケージ名と言うこともある
function GetPackageFamilyName(hProcess: THANDLE; Size: PDWORD; Path: PWideChar):
DWORD; stdcall; external 'kernel32.dll';
本サンプルでは,フォームに配置した TMemo に取得した値を表示します.
最初の値は GetApplicationUserModelId 関数で取得した以下の AppUserModelId の値です.この値とコールバック関数の引数 (lPara) の値が一致すれば,その時のウィンドウハンドルの値が検索対象のアプリのウィンドウハンドルの値です. |
Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint |
その次の値は,そのウィンドウのプロセスのハンドルを取得して,QueryFullProcessImageNameW 関数でフルパスを取得した結果です.
UWP アプリの場合,全てこの値になります. |
C:\Windows\System32\ApplicationFrameHost.exe |
以下は最後の値です.これは,検索対象の UWP アプリの EXE のフルパスです.この EXE ファイルは,インストール先のフォルダ内にあります.UWP アプリは,この EXE からは起動でききません.インストール先のパッケージ名は,UWP アプリのバージョンが変わると変わる可能性があります. |
C:\Program Files\WindowsApps\Microsoft.MSPaint_6.2105.4017.0_x64__8wekyb3d8bbwe\PaintStudio.View.exe |
UWP アプリのトップレベルのウィンドウのクラス名は ApplicationFrameWindow です.このウィンドウの階層直下に,クラス名が Windows.UI.Core.CoreWindow まウィンドウがあります.GetApplicationUserModelId 関数は,そのウィンドウのプロセスハンドルの値を使用して取得します.クラス名が ApplicationFrameWindow のウィンドウのプロセスハンドルからは取得できません.EXE のフルパスも同じです.
UWP アプリのウィンドウが最小化状態になると,クラス名が Windows.UI.Core.CoreWindow のウィンドウは切り離されて独立したトップレベルのウィンドウになります.このウィンドウは,バックグラウンドのプロセスとして実行されます.したがって,このサンプルは,対象の UWP アプリが最小化状態の時は,起動していない判定となります. |
|
図3
実行時の画面 |
リスト3
プロセスのハンドルから AppUserModelId
の値や UWP アプリの EXE のフルパスを取得 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function GetApplicationUserModelId(hProcess: THandle; Size: PDWORD;
AppId: PWideChar): DWORD; stdcall; external 'kernelBase.dll';
function QueryFullProcessImageNameW(Process: THandle; Flags: DWORD;
Buffer: PWideChar; Size: PDWORD): DWORD; stdcall; external 'kernel32.dll';
function EnumWindowProc(hWindow: HWND; lPara: LPARAM): Boolean; stdcall;
var
Form1: TForm1;
implementation
uses
Winapi.Dwmapi,
Winapi.ShellAPI,
Winapi.ActiveX;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// テスト用の AppUserModelId の値をセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
// ペイント 3D
Edit1.Text:= 'Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint';
end;
//=============================================================================
// 特定の AppUserModelId の UWP アプリが起動しているかを確認
// プロセスのハンドルと GetApplicationUserModelId 関数の動作確認用
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LAppId : string;
LArgAppId : string;
LTargetWnd : HWND;
LText : string;
begin
Memo1.Lines.Clear;
LAppId := Trim(Edit1.Text);
LArgAppId := LAppId;
EnumWindows(@EnumWindowProc, LPARAM(@LArgAppId));
LTargetWnd := StrToIntDef(LArgAppId, 0);
if LTargetWnd = 0 then begin
Memo1.Lines.Add('起動していないか最小化状態です。');
end;
end;
//=============================================================================
// アプリを起動
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LShellPath : string;
begin
LShellPath := 'shell:AppsFolder\' + Trim(Edit1.Text);
ShellExecute(0, '', PChar(LShellPath), nil, nil, SW_SHOW);
end;
//-----------------------------------------------------------------------------
// EnumWindows のコールバック関数
// 引数 (lPara - AppUserModelId の値) と同じ UWP アプリが起動しているかをチェック
// 検出したら引数 (lPara) にそのウィンドウハンドルの値を文字列にして渡す
//-----------------------------------------------------------------------------
function EnumWindowProc(hWindow: HWND; lPara: LPARAM): Boolean; stdcall;
const
UWP_FRAMEWND = 'ApplicationFrameWindow';
UWP_COREWND = 'Windows.UI.Core.CoreWindow';
DWMWA_CLOAKED = 14;
PROCESS_QUERY_LIMITED_INFORMATION = $1000;
var
LCloaked : BOOL;
LCoreWnd : HWND;
LProcessID : DWORD;
LhProcess : THandle;
LBuffer : array [0..MAX_PATH - 1] of Char;
LSTR_SIZE : DWORD;
LResText : string;
LExePath1 : string;
LExePath2 : string;
begin
Result := True;
if GetWindow(hWindow, GW_OWNER) <> 0 then exit;
if not IsWindowVisible(hWindow) then exit;
// 待機中またはバックグラウンドのウィンドウは対象外
DwmGetWindowAttribute(hWindow, DWMWA_CLOAKED, @LCloaked, SizeOf(LCloaked));
if LCloaked then Exit;
// ウィンドウのクラス名が ApplicationFrameWindow の プロセスIDを取得
// その値からプロセスのオープンハンドル取得
// そのプロセスハンドルから EXE のフルパスを取得
// 一般のデスクトップアプリは,これで EXE のフルパスが取得できる
GetWindowThreadProcessId(hWindow, @LProcessID);
LhProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, LProcessID);
try
// EXE のフルパスを取得
FillChar(LBuffer, SizeOf(LBuffer), #0);
LSTR_SIZE := Length(LBuffer);
LExePath1:='';
if QueryFullProcessImageNameW(LhProcess,
0,
@LBuffer[0],
@LSTR_SIZE) = 0 then Exit;
LExePath1 := LBuffer;
finally
CloseHandle(LhProcess);
end;
// ウィンドウのクラス名が Windows.UI.Core.CoreWindow のウィンドウハンドルを取得
// このウィンドはクラス名が ApplicationFrameWindow のウィンドウの階層下にある
// このウィンドウは最小化状態の時は ApplicationFrameWindow の階層下に存在しない
LCoreWnd := FindWindowEx(hWindow, 0, UWP_COREWND, nil);
if LCoreWnd = 0 then Exit;
// ウィンドウのクラス名が Windows.UI.Core.CoreWindow の プロセスIDを取得
// その値からプロセスのオープンハンドル取得
// そのプロセスハンドルから AppUserModelId の値と EXE のフルパスを取得
GetWindowThreadProcessId(LCoreWnd, @LProcessID);
LhProcess := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, False, LProcessID);
try
// AppUserModelId の値を取得
LSTR_SIZE := SizeOf(LBuffer);
FillChar(LBuffer, SizeOf(LBuffer), #0);
GetApplicationUserModelId(LhProcess, @LSTR_SIZE, @LBuffer);
LResText := LBuffer;
// 取得した値と引数 (lPara) の値が同じなら検索終了
if SameText(LResText, PString(lPara)^) then begin
PString(lPara)^ := IntToStr(hWindow);
Result := False;
// EXE のフルパスを取得
FillChar(LBuffer, SizeOf(LBuffer), #0);
LSTR_SIZE := Length(LBuffer);
LExePath2:='';
if QueryFullProcessImageNameW(LhProcess,
0,
@LBuffer[0],
@LSTR_SIZE) = 0 then Exit;
LExePath2 := LBuffer;
// 取得した値を表示 ]
Form1.Memo1.Lines.Add(LResText);
Form1.Memo1.Lines.Add(LExePath1);
Form1.Memo1.Lines.Add(LExePath2);
end;
finally
CloseHandle(LhProcess);
end;
end;
end.
03_AppUserModelId の値からアプリ名を取得 |
SHGetFileInfo 関数を使用すると,AppUserModelId の値からアプリ名を取得できます. |
|
図4
ペイント 3D の AppuserModelId の値からアプリ名を取得した結果 |
リスト4
AppUserModelId の値からアプリ名を取得.SHGetFileInfo 関数を使用 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function AppUserModelIdToAppName(const AppId: string): string;
var
Form1: TForm1;
implementation
uses
Winapi.ShellAPI,
Winapi.ActiveX,
Winapi.ShlObj;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// テスト用の AppUserModelId の値をセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
// ペイント 3D
Edit1.Text:= 'Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint';
// メモ帳
// Edit1.Text := '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\notepad.exe';
end;
//=============================================================================
// AppUserModelId の値からアプリ名を取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LAppId : string;
LAppName : string;
LText : string;
begin
LAppId := Trim(Edit1.Text);
LAppName := AppUserModelIdToAppName(LAppId);
if LAppName = '' then begin
LText := '該当するアプリが見つかりませんでした。';
MessageBox(Handle, PChar(LText), 'アプリ名', MB_TOPMOST or MB_ICONWARNING);
end else begin
LText := 'アプリ名' + sLineBreak + LAppName;
MessageBox(Handle, PChar(LText), 'アプリ名', MB_TOPMOST or MB_ICONINFORMATION);
end;
end;
//=============================================================================
// アプリを起動
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LShellPath : string;
begin
LShellPath := 'shell:AppsFolder\' + Trim(Edit1.Text);
ShellExecute(0, '', PChar(LShellPath), nil, nil, SW_SHOW);
end;
//-----------------------------------------------------------------------------
// AppUserModelId の値からアプリ名を取得する関数
// SHGetFileInfo 関数を使用
//-----------------------------------------------------------------------------
function AppUserModelIdToAppName(const AppId: string): string;
var
LShellPath : string;
LFileInfo : TSHFileInfo;
LpidlAppId : PItemIDList;
begin
Result := '';
LShellPath := 'shell:AppsFolder\' + AppId;
LpidlAppId := ILCreateFromPath(PChar(LShellPath));
if ILIsEmpty(LpidlAppId) then Exit;
SHGetFileInfo(Pointer(LpidlAppId),
0,
LFileInfo,
SizeOf(TSHFileInfo),
SHGFI_PIDL or SHGFI_DISPLAYNAME);
CoTaskMemFree(LpidlAppId);
Result := LFileInfo.szDisplayName;
end;
end.
以下のリンクの記事のサンプルのように,IShellItem インターフェイスを使用しても,AppUserModelId の値からアプリ名を取得することができます. |
リスト5
AppUserModelId の値からアプリ名を取得.IShellItem を使用 |
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics,Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
function AppUserModelIdToAppName(const AppId: string): string;
var
Form1: TForm1;
implementation
uses
Winapi.ShellAPI,
Winapi.ActiveX,
Winapi.ShlObj;
{$R *.dfm}
//=============================================================================
// フォーム生成時の処理
// テスト用の AppUserModelId の値をセット
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
// ペイント 3D
Edit1.Text:= 'Microsoft.MSPaint_8wekyb3d8bbwe!Microsoft.MSPaint';
// メモ帳
// Edit1.Text := '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\notepad.exe';
end;
//=============================================================================
// AppUserModelId の値からアプリ名を取得
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LAppId : string;
LAppName : string;
LText : string;
begin
LAppId := Trim(Edit1.Text);
LAppName := AppUserModelIdToAppName(LAppId);
if LAppName = '' then begin
LText := '該当するアプリが見つかりませんでした。';
MessageBox(Handle, PChar(LText), 'アプリ名', MB_TOPMOST or MB_ICONWARNING);
end else begin
LText := 'アプリ名' + sLineBreak + LAppName;
MessageBox(Handle, PChar(LText), 'アプリ名', MB_TOPMOST or MB_ICONINFORMATION);
end;
end;
//=============================================================================
// アプリを起動
//=============================================================================
procedure TForm1.Button2Click(Sender: TObject);
var
LShellPath : string;
begin
LShellPath := 'shell:AppsFolder\' + Trim(Edit1.Text);
ShellExecute(0, '', PChar(LShellPath), nil, nil, SW_SHOW);
end;
//-----------------------------------------------------------------------------
// AppUserModelId の値からアプリ名を取得する関数
// IShellItem を使用
//-----------------------------------------------------------------------------
function AppUserModelIdToAppName(const AppId: string): string;
var
LAppId : string;
LpidlAppID : PItemIDList;
LShItem : IShellItem;
LAppIdName : PWideChar;
begin
Result := '';
LAppId := 'shell:AppsFolder\' + AppId;
LpidlAppID := ILCreateFromPath(PChar(LAppId));
if ILIsEmpty(LpidlAppID) then Exit;
// 項目識別子の IShellItem オブジェクトを取得してその表示名を取得
SHCreateItemFromIDList(LpidlAppID, IShellItem, LShItem);
LShItem.GetDisplayName(SIGDN_NORMALDISPLAY, LAppIdName);
LShItem := nil;
CoTaskMemFree(LpidlAppID);
Result := LAppIdName;
end;
end.
04_[ バックラウンドで実行 ] の機能を無効にする方法 |
[設定] アプリで,UWP アプリの
[バックグラウンドで実行] の機能をアプリ単位で設定できます.次のコマンドを実行して設定画面を表示します. |
下図のように,対象のアプリのスイッチをオフにします.コンピュータを再起動して,本ページの最初のサンプルを実行すれば,起動したペイント 3D を閉じると [起動していません] と表示するようになります.
コンピュータを再起動しない場合は,バックグラウンドで実行しているアプリはそのままバックグラウンドで実行されたままです.スイッチをオフにしても,バックグラウンドで実行中のアプリは終了しません. |
|
図5
[バックグラウンドで実行] の機能を無効にする |
|