如何在Delphi中检测通用Windows平台(UWP)

3
为了将用Delphi编写的应用程序提交到Windows Store,我必须禁用内部更新机制。例如,“检查更新”之类的东西是通过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错误,没有其他错误。

1个回答

6
函数导入不正确。应该是:
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#代码中存在一些错误,我没有复制。


第一次调用 GetCurrentPackageFullName(Len, nil) 总是返回代码 122 (ERROR_INSUFFICIENT_BUFFER)。但无论如何,Len变量都被正确填充,名称也是如此。非常感谢! - Anse
我的错误。它被清楚地记录下来,而我没有付足够的注意力。现在已经修复了。 - David Heffernan

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