我在使用 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();
}
}
我知道这不是很多代码,但我一直在用自己的时间进行开发,以尽快将其推出。在这个方法中,我可以逻辑地认为真正发生的唯一两件事导致了问题如下:
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));
}
}
}
实际使用的文件路径:
我知道它可以在这里写,因为它将文件写入 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 问题回复
在这一点上,我有点不知所措,互联网并没有真正把我带到任何具体的地方,我只是不知道什么可能会遇到问题。
好吧,经过一个早上的清晰之后,我决定完成注释代码和创建旁加载应用程序包的过程。我确定问题出在名为
TiktokenSharp
的第 3 方包
TikTokenSharp 用于
OpenAiCreatePrompt
方法中的一个实用程序类,我用它来确定是否需要递归删除对话,直到我处于指定的 Max Token Count.
TikTokenSharp 有一个名为
CoreBPE
的内部类,它用于计算一个字符串有多少个标记。我不太清楚是什么导致了这个问题,但要么它没有被添加到包中,要么它在 WindowsApps 文件夹的上下文中做了一些奇怪的事情,这导致一些拒绝访问异常在 KernalBase.dll 模块后面被混淆。
这意味着我只需要编写自己的令牌长度解析器;真的应该从一开始就自己做。