WinUI3 应用程序在 Debug、Release 中运行,但在 SideLoaded 或 Published to Store 时失败

问题描述 投票:0回答:1

我在使用 WinUI 3 应用程序时遇到了一些本机异常。作为序言,我之前已经在没有太多戏剧性的情况下将应用程序发布到 Microsoft Store(尽管我们最近不谈论 MSIX 打包的状态)。

当我在调试模式(x32 或 x64)或发布模式下运行我的应用程序时,我没有任何问题,一切都按预期工作。当我通过旁加载安装或从商店的直接链接下载它时,我遇到了这个异常:

Access to the path 'C:\Program Files\WindowsApps\[PUBLISHERNAME].329567E69597C_1.0.12.0_x86__1wwrtwbj9qrjm\bpe' is denied.'.

我应该声明该应用程序可以正常加载和启动,我可以在窗口中导航,并且我认为以下方法正在触发一些底层异常。

public async void SendPrompt()
{
    // Add to the conversation list
    Conversation.Add(new ChatMessage(UserPrompt, DateTime.UtcNow, Direction.User));

    // clear messsage
    UserPrompt = string.Empty;

    var dispatcher = Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread();

    dispatcher.TryEnqueue(() =>
    {
        // set awaiting response bar
        IsAwaitingResponse = !IsAwaitingResponse;
    });

    // create open AI response
    UserPrompt prompt = null;

    switch (chatSettings.OpenAiType)
    {
        case OpenAiType.API:
            prompt = oAiService.OpenAiCreatePrompt(
                SystemMessage,
                Conversation.GetRange(conversationStartingIndex,
                Conversation.Count - conversationStartingIndex).ToList(),
                chatSettings.ChatDefaults.MaxTokenLength,
                TemperatureValue,
                MaxTokenLength,
                TopP,
                FrequencyPenalty,
                PresencePenalty,
                null);
            break;
        case OpenAiType.AZURE:
            prompt = oAiService.AzureCreatePrompt(SystemMessage,
                Conversation.GetRange(conversationStartingIndex,
                Conversation.Count - conversationStartingIndex).ToList(),
                chatSettings.ChatDefaults.MaxTokenLength,
                TemperatureValue,
                MaxTokenLength,
                TopP,
                FrequencyPenalty,
                PresencePenalty,
                new string[] { "<|im_end|>" });
            break;
    }

    if (prompt != null)
    {
        conversationStartingIndex = prompt.ConversationStartingIndex;
        var response = new BaseGPTResponse();
        switch (chatSettings.OpenAiType)
        {
            case OpenAiType.API:
                response = await oAiService.CompletionCreateAsync<ChatGPTOpenAiResponse>(prompt.Content);
                break;
            case OpenAiType.AZURE:
                response = await oAiService.CompletionCreateAsync<ChatGPTAzureResponse>(prompt.Content);
                break;
        }

        ChatMessage? chatMessage = null;
        if (response.hasErrored)
        {
            // record response from chatGPT
            Conversation.Add(new ChatMessage($"Error processing message: {response.errorResponse}", DateTime.UtcNow, Direction.Assistant, response.hasErrored));
        }
        else
        {
            // create chat message specific to settings type in use.
            var botResponse = string.Empty;
            switch (chatSettings.OpenAiType)
            {
                case OpenAiType.API:
                    botResponse = (response as ChatGPTOpenAiResponse)?.choices[0].message.content;
                    break;
                case OpenAiType.AZURE:
                    botResponse = (response as ChatGPTAzureResponse)?.choices[0].text;
                    break;
            }

            // record response from chatGPT
            Conversation.Add(new ChatMessage(botResponse, DateTime.UtcNow, Direction.Assistant, response.hasErrored));
        }

        // save/overwrite conversation data.
        await UpdateConversationStores();
    }
}

我知道这不是很多代码,但我一直在用自己的时间进行开发,以尽快将其推出。在这个方法中,我可以逻辑地认为真正发生的唯一两件事导致了问题如下:

  • 在服务中使用 HttpClient 进行 Post 调用。
  • 如果可用,使用助手从 LocalSettings 中提取目录路径数据 类。
  • 在属于这个的目录中存储/覆盖文件 一点代码
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
    我认为这是一个重定向的文件夹路径实际上不是你得到的 当你调试它时。

我知道我可以在创建一个我可以看到的文件夹结构时写入该位置,并在我为映射 Shell 菜单项创建的其他目录之一中保存/创建一个文件。

上下文的文件服务(我相信是由 WinUI Template Studio 创建的)

public class FileService : IFileService
{
    public T Read<T>(string folderPath, string fileName)
    {
        var path = Path.Combine(folderPath, fileName);
        if (File.Exists(path))
        {
            var json = File.ReadAllText(path);
            return JsonConvert.DeserializeObject<T>(json);
        }

        return default;
    }

    public void Save<T>(string folderPath, string fileName, T content)
    {
        if (!Directory.Exists(folderPath))
        {
            Directory.CreateDirectory(folderPath);
        }

        var fileContent = JsonConvert.SerializeObject(content);
        File.WriteAllText(Path.Combine(folderPath, fileName), fileContent, Encoding.UTF8);
    }

    public void Delete(string folderPath, string fileName)
    {
        if (fileName != null && File.Exists(Path.Combine(folderPath, fileName)))
        {
            File.Delete(Path.Combine(folderPath, fileName));
        }
    }
}

实际使用的文件路径:

  • C:\Users[USERNAME]\AppData\Local\Packages[PUBLISHERNAME].329567E69597C_1wwrtwbj9qrjm\LocalCache\Local[FOLDERNAME]\Conversations
  • C:\Users[USERNAME]\AppData\Local\Packages[PUBLISHERNAME].329567E69597C_1wwrtwbj9qrjm\LocalCache\Local[文件夹名称]\Maps

我知道它可以在这里写,因为它将文件写入 Map 文件夹,我可以亲眼看到它。

输出控制台的一些额外输出行

我使用 Debug > Other Debug Targets > Debug Installed App Package 附加调试器

Exception thrown at 0x75557922 (KernelBase.dll) in [APPNAMESPACE].exe: 0xE0434352 (parameters: 0x80070005, 0x00000000, 0x00000000, 0x00000000, 0x797E0000).
onecore\com\combase\registrationstore\registrationstoredata.cpp(1055)\combase.dll!765BF0D5: (caller: 76581A4C) ReturnHr(407) tid(37590) 80070002 The system cannot find the file specified.
onecore\com\combase\registrationstore\registrationstoredata.cpp(1055)\combase.dll!765BF0D5: (caller: 76581A4C) ReturnHr(408) tid(37590) 80070002 The system cannot find the file specified.
Exception thrown at 0x75557922 (KernelBase.dll) in [APPNAMESPACE].exe: 0xE0434352 (parameters: 0x80070005, 0x00000000, 0x00000000, 0x00000000, 0x797E0000).
Exception thrown at 0x75557922 (KernelBase.dll) in [APPNAMESPACE].exe: WinRT originate error - 0x80070005 : 'Access to the path 'C:\Program Files\WindowsApps\[PUBLISHERNAME].329567E69597C_1.0.12.0_x86__1wwrtwbj9qrjm\bpe' is denied.'.
Unhandled exception at 0x0B791B70 (Microsoft.ui.xaml.dll) in [APPNAMESPACE].exe: 0xC000027B: An application-internal exception has occurred (parameters: 0x2102A6A0, 0x00000002).

我已经发布了一些对一些 GitHub 问题的回复,即这个问题,因为我今天大部分时间都在处理这个问题GitHub 问题回复

在这一点上,我有点不知所措,互联网并没有真正把我带到任何具体的地方,我只是不知道什么可能会遇到问题。

c# .net uwp winui-3 msix
1个回答
0
投票

好吧,经过一个早上的清晰之后,我决定完成注释代码和创建旁加载应用程序包的过程。我确定问题出在名为

TiktokenSharp

的第 3 方包

TikTokenSharp 用于

OpenAiCreatePrompt
方法中的一个实用程序类,我用它来确定是否需要递归删除对话,直到我处于指定的 Max Token Count.

TikTokenSharp 有一个名为

CoreBPE
的内部类,它用于计算一个字符串有多少个标记。我不太清楚是什么导致了这个问题,但要么它没有被添加到包中,要么它在 WindowsApps 文件夹的上下文中做了一些奇怪的事情,这导致一些拒绝访问异常在 KernalBase.dll 模块后面被混淆。

这意味着我只需要编写自己的令牌长度解析器;真的应该从一开始就自己做。

© www.soinside.com 2019 - 2024. All rights reserved.