WinUI3 Application runs in Debug, Release, but fails when SideLoaded or Published to Store

huangapple go评论52阅读模式
英文:

WinUI3 Application runs in Debug, Release, but fails when SideLoaded or Published to Store

问题

I'm running into a bit of a brick wall with a native exception I'm seeing with my WinUI 3 application. To preface this, I've published apps to the Microsoft Store before without too much drama (Altough let's not talk about the state of MSIX packaging lately).

When I run my app in Debug mode (x32 or x64) or Release I have no issues, everything works as expected. When I run it via sideloaded installation, or by downloading it from the direct link from the store I hit this exception:

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

I should state that the app loads and starts up fine, I can navigate through windows and it's the following method that I believe some underlying exception is being hit.

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

// clear message
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();
}

}

I know it's not a great bit of code, but I've been crunching development in my own time to get this out the door as soon as I can. The only two things that really happens that I can logically see as causing an issue within this method are as follows:

  • Uses HttpClient within the services to make a Post call.
  • Pulls directory path data from LocalSettings if available using a helper class.
  • Stores/Overwrites files in the directory that belongs to this bit of code Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) which I believe is a redirected folder path not actually what you get when you debug it.

I know I can write to that location as I create a folder structure which I can see, and save/create a file in one of the other directories I've created for mapping Shell Menu Items.

FileService for Context (Created by the WinUI Template Studio I believe)

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

}

Actual File Paths Used:

  • C:\Users[USERNAME]\AppData\Local\Packages[PUBLISHERNAME].329567E69597C_1wwrtwbj9qrjm\LocalCache\Local[FOLDERNAME]\Conversations
  • C:\Users[USERNAME]\AppData\Local\Packages[PUBLISHERNAME].329567E69597C_1wwrtwbj9qrjm\LocalCache\Local[FOLDERNAME]\Maps

I know it can write here as it writes a file into the Map folder and I can physically see it.

Some additional output lines from the Output console

I'm attaching the debugger using 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,

英文:

I'm running into a bit of a brick wall with a native exception I'm seeing with my WinUI 3 application. To preface this, I've published apps to the Microsoft Store before without too much drama (Altough let's not talk about the state of MSIX packaging lately).

When I run my app in Debug mode (x32 or x64) or Release I have no issues, everything works as expected. When I run it via sideloaded installation, or by downloading it from the direct link from the store I hit this exception:

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

I should state that the app loads and starts up fine, I can navigate through windows and it's the following method that I believe some underlaying exception is being hit.

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(() =&gt;
	{
		// 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[] { &quot;&lt;|im_end|&gt;&quot; });
			break;
	}

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

		ChatMessage? chatMessage = null;
		if (response.hasErrored)
		{
			// record response from chatGPT
			Conversation.Add(new ChatMessage($&quot;Error processing message: {response.errorResponse}&quot;, 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();
	}
}

I know it's not a great bit of code, but I've been crunching development in my own time to get this out the door as soon as I can. The only two things that really happens that I can logically see as causing an issue within this method are as follows:

  • Uses HttpClient within the services to make a Post call.
  • Pulls directory path data from LocalSettings if available using a helper
    class.
  • Stores/Overwrites files in the directory that belongs to this
    bit of code
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
    which I believe is a redirected folder path not actually what you get
    when you debug it.

I know I can write to that location as I create a folder structure which I can see, and save/create a file in one of the other directories I've created for mapping Shell Menu Items.

FileService for Context (Created by the WinUI Template Studio I believe)

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

        return default;
    }

    public void Save&lt;T&gt;(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 &amp;&amp; File.Exists(Path.Combine(folderPath, fileName)))
        {
            File.Delete(Path.Combine(folderPath, fileName));
        }
    }
}

Actual File Paths Used:

  • C:\Users[USERNAME]\AppData\Local\Packages[PUBLISHERNAME].329567E69597C_1wwrtwbj9qrjm\LocalCache\Local[FOLDERNAME]\Conversations
  • C:\Users[USERNAME]\AppData\Local\Packages[PUBLISHERNAME].329567E69597C_1wwrtwbj9qrjm\LocalCache\Local[FOLDERNAME]\Maps

I know it can write here as it writes a file into the Map folder and I can physically see it.

Some additional output lines from the Output console

I'm attaching the debugger using 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 : &#39;Access to the path &#39;C:\Program Files\WindowsApps\[PUBLISHERNAME].329567E69597C_1.0.12.0_x86__1wwrtwbj9qrjm\bpe&#39; is denied.&#39;.
Unhandled exception at 0x0B791B70 (Microsoft.ui.xaml.dll) in [APPNAMESPACE].exe: 0xC000027B: An application-internal exception has occurred (parameters: 0x2102A6A0, 0x00000002).

I have posted some replies to some GitHub issues, namely this one, as I have been working on this problem most of today GitHub Issue Reply

At this point I'm at a bit of a loss and the internet hasn't really lead me anywhere concrete, I simply do not know what could be hitting an issue.

答案1

得分: 0

Well after a morning of clarity I decided to go through the process of commenting out code and creating the sideloaded app packages. I identified that the issue was coming from a 3rd party package called TiktokenSharp

TikTokenSharp is used in a utility class within the OpenAiCreatePrompt method that I use to determine if I need to recursively remove conversations until I'm under a specified Max Token Count.

Well TikTokenSharp has an internal class called CoreBPE that it's using to calculate how many tokens a string is. I can't quite tell exactly what is causing the issue, but either it's not getting added to the package or it's doing something weird in the context of the WindowsApps folder which is causing some Access Denied exceptions being obfuscated behind the KernalBase.dll module.

This means I'll need to just write my own Token length parser; should have done it myself from the start really.

英文:

Well after a morning of clarity I decided to go through the process of commenting out code and creating the sideloaded app packages. I identified that the issue was coming from a 3rd party package called TiktokenSharp

TikTokenSharp is used in a utlity class within the OpenAiCreatePrompt method that I use to determine if I need to recursively remove conversations until I'm under a specified Max Token Count.

Well TikTokenSharp has an internal class called CoreBPE that it's using to calculate how many tokens a string is. I can't quite tell exactly what is causing the issue, but either it's not getting added to the package or it's doing something weird in the context of the WindowsApps folder which is causing some Access Denied exceptions being obfuscated behind the KernalBase.dll module.

This means I'll need to just write my own Token length parser; should have done it myself from the start really.

huangapple
  • 本文由 发表于 2023年3月31日 04:26:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75892711.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定