如何在 Delphi 中检测通用 Windows 平台 (UWP)
How to detect Universal Windows Platform (UWP) in Delphi
要将用 Delphi 编写的应用程序添加到 Windows 商店,我必须禁用内部更新机制。例如像 "Check for updates" 这样的东西是通过 Store policies 10.2.5
禁止的
所以,我在 DesktopBridgeHelpers project code 中找到了 C# 辅助函数 IsRunningAsUwp()
。我的计划是将该助手转换为 Delphi 代码,但 packageFullName
字符串在这里始终为空,即使我 运行 通过 DesktopBridge 转换项目的应用程序也是如此:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
public bool IsRunningAsUwp()
{
if (IsWindows7OrLower)
{
return false;
}
else
{
int length = 0;
StringBuilder sb = new StringBuilder(0);
int result = GetCurrentPackageFullName(ref length, sb);
sb = new StringBuilder(length);
result = GetCurrentPackageFullName(ref length, sb);
return result != APPMODEL_ERROR_NO_PACKAGE;
}
}
我当前的(不工作)Delphi 转换看起来像这样:
function GetCurrentPackageFullName(out Length: DWORD; out fullName: String): DWORD; stdcall; external kernel32 delayed;
function RunningAsUwp: Boolean;
const
APPMODEL_ERROR_NO_PACKAGE = 15700;
var
PackageName: String;
PackageLen, PackageResult: DWORD;
begin
if (Win32MajorVersion < 6) or ((Win32MajorVersion = 6) and (Win32MinorVersion <= 1)) then begin
// Windows 7 or older
Result := False;
end else begin
// Windows 10, but not necessarily a Store App
PackageLen := 0;
SetLength(PackageName, 1024);
PackageResult := GetCurrentPackageFullName(PackageLen, PackageName);
showmessage(PackageName); // <= always empty
if PackageResult = APPMODEL_ERROR_NO_PACKAGE then begin
Result := False;
end else if not String(PackageName).IsEmpty then begin
Result := True;
end else begin
Result := False;
end;
end;
end;
当运行通过已安装的 appx 包时,我没有收到其他错误,只有那个空的 PackageName。
函数导入不正确。应该是
function GetCurrentPackageFullName(
out Len: Cardinal;
Name: PWideChar
): Integer; stdcall; external kernel32 delayed;
然后调用它你这样做:
var
Len: Cardinal;
Name: string;
ErrorCode: Integer;
....
Len := 0;
ErrorCode := GetCurrentPackageFullName(Len, nil);
if ErrorCode <> ERROR_INSUFFICIENT_BUFFER then
RaiseLastOSError(ErrorCode);
SetLength(Name, Len-1);
ErrorCode := GetCurrentPackageFullName(Len, PChar(Name));
if ErrorCode <> ERROR_SUCCESS then
RaiseLastOSError(ErrorCode);
您可能希望以不同的方式处理错误,但我相信您可以解决。
请注意,C# 代码有一些我没有重现的错误。
要将用 Delphi 编写的应用程序添加到 Windows 商店,我必须禁用内部更新机制。例如像 "Check for updates" 这样的东西是通过 Store policies 10.2.5
禁止的所以,我在 DesktopBridgeHelpers project code 中找到了 C# 辅助函数 IsRunningAsUwp()
。我的计划是将该助手转换为 Delphi 代码,但 packageFullName
字符串在这里始终为空,即使我 运行 通过 DesktopBridge 转换项目的应用程序也是如此:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
public bool IsRunningAsUwp()
{
if (IsWindows7OrLower)
{
return false;
}
else
{
int length = 0;
StringBuilder sb = new StringBuilder(0);
int result = GetCurrentPackageFullName(ref length, sb);
sb = new StringBuilder(length);
result = GetCurrentPackageFullName(ref length, sb);
return result != APPMODEL_ERROR_NO_PACKAGE;
}
}
我当前的(不工作)Delphi 转换看起来像这样:
function GetCurrentPackageFullName(out Length: DWORD; out fullName: String): DWORD; stdcall; external kernel32 delayed;
function RunningAsUwp: Boolean;
const
APPMODEL_ERROR_NO_PACKAGE = 15700;
var
PackageName: String;
PackageLen, PackageResult: DWORD;
begin
if (Win32MajorVersion < 6) or ((Win32MajorVersion = 6) and (Win32MinorVersion <= 1)) then begin
// Windows 7 or older
Result := False;
end else begin
// Windows 10, but not necessarily a Store App
PackageLen := 0;
SetLength(PackageName, 1024);
PackageResult := GetCurrentPackageFullName(PackageLen, PackageName);
showmessage(PackageName); // <= always empty
if PackageResult = APPMODEL_ERROR_NO_PACKAGE then begin
Result := False;
end else if not String(PackageName).IsEmpty then begin
Result := True;
end else begin
Result := False;
end;
end;
end;
当运行通过已安装的 appx 包时,我没有收到其他错误,只有那个空的 PackageName。
函数导入不正确。应该是
function GetCurrentPackageFullName(
out Len: Cardinal;
Name: PWideChar
): Integer; stdcall; external kernel32 delayed;
然后调用它你这样做:
var
Len: Cardinal;
Name: string;
ErrorCode: Integer;
....
Len := 0;
ErrorCode := GetCurrentPackageFullName(Len, nil);
if ErrorCode <> ERROR_INSUFFICIENT_BUFFER then
RaiseLastOSError(ErrorCode);
SetLength(Name, Len-1);
ErrorCode := GetCurrentPackageFullName(Len, PChar(Name));
if ErrorCode <> ERROR_SUCCESS then
RaiseLastOSError(ErrorCode);
您可能希望以不同的方式处理错误,但我相信您可以解决。
请注意,C# 代码有一些我没有重现的错误。