Include app Microsoft-Windows-AppXDeploymentServer-Operational event log as part of bug report (#40098)

<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request

We are missing msix setup event log from
Microsoft-Windows-AppXDeploymentServer-Operational from bug report.
This PR includes it back for any installation with Powertoys or
CommandPalette

Attach the sample one capture after I setup PowerToys for
Microsoft-Windows-AppXDeploymentServer-Operational events

[EventViewer-AppXDeploymentServerEventLog.zip](https://github.com/user-attachments/files/20791324/EventViewer-AppXDeploymentServerEventLog.zip)

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
This commit is contained in:
Gordon Lam 2025-06-18 17:22:17 -07:00 committed by Gordon Lam (SH)
parent c2d511afbc
commit 33050e80ae
5 changed files with 70 additions and 8 deletions

View File

@ -1965,6 +1965,7 @@ Wwanpp
XAxis XAxis
xclip xclip
xcopy xcopy
XDeployment
XDocument XDocument
XElement XElement
xfd xfd

View File

@ -17,6 +17,7 @@ The bug report includes the following files:
* `context-menu-packages.txt` - Information about the packages that are registered for the new Windows 11 context menu. * `context-menu-packages.txt` - Information about the packages that are registered for the new Windows 11 context menu.
* `dotnet-installation-info.txt` - Information about the installed .NET versions. * `dotnet-installation-info.txt` - Information about the installed .NET versions.
* `EventViewer-*.xml` - These files contain event logs from the Windows Event Viewer for the executable specified in the file name. * `EventViewer-*.xml` - These files contain event logs from the Windows Event Viewer for the executable specified in the file name.
* `EventViewer-Microsoft-Windows-AppXDeploymentServer/Operational.xml` - Contains event logs from the AppXDeployment-Server which are useful for diagnosing MSIX installation issues.
* `gpo-configuration-info.txt` - Information about the configured [GPO](/doc/gpo/README.md). * `gpo-configuration-info.txt` - Information about the configured [GPO](/doc/gpo/README.md).
* `installationFolderStructure.txt` - Information about the folder structure of the installation. All lines with files have the following structure: `FileName Version MD5Hash`. * `installationFolderStructure.txt` - Information about the folder structure of the installation. All lines with files have the following structure: `FileName Version MD5Hash`.
* `last_version_run.json` - Information about the last version of PowerToys that was run. * `last_version_run.json` - Information about the last version of PowerToys that was run.

View File

@ -23,7 +23,7 @@ namespace
// Report last 30 days // Report last 30 days
const long long PERIOD = 10 * 24 * 3600ll * 1000; const long long PERIOD = 10 * 24 * 3600ll * 1000;
const std::wstring QUERY = L"<QueryList>" \ const std::wstring QUERY_BY_PROCESS = L"<QueryList>" \
L" <Query Id='0'>" \ L" <Query Id='0'>" \
L" <Select Path='Application'>" \ L" <Select Path='Application'>" \
L" *[System[TimeCreated[timediff(@SystemTime)&lt;%I64u]]] " \ L" *[System[TimeCreated[timediff(@SystemTime)&lt;%I64u]]] " \
@ -32,16 +32,46 @@ namespace
L" </Query>" \ L" </Query>" \
L"</QueryList>"; L"</QueryList>";
const std::wstring QUERY_BY_CHANNEL = L"<QueryList>" \
L" <Query Id='0'>" \
L" <Select Path='%s'>" \
L" *[System[TimeCreated[timediff(@SystemTime)&lt;%I64u]]]" \
L" </Select>" \
L" </Query>" \
L"</QueryList>";
std::wstring GetQuery(std::wstring processName) std::wstring GetQuery(std::wstring processName)
{ {
wchar_t buff[1000]; wchar_t buff[1000];
memset(buff, 0, sizeof(buff)); memset(buff, 0, sizeof(buff));
_snwprintf_s(buff, sizeof(buff), QUERY.c_str(), PERIOD, processName.c_str()); _snwprintf_s(buff, sizeof(buff), QUERY_BY_PROCESS.c_str(), PERIOD, processName.c_str());
return buff;
}
std::wstring GetQueryByChannel(std::wstring channelName)
{
wchar_t buff[1000];
memset(buff, 0, sizeof(buff));
_snwprintf_s(buff, sizeof(buff), QUERY_BY_CHANNEL.c_str(), channelName.c_str(), PERIOD);
return buff; return buff;
} }
std::wofstream report; std::wofstream report;
EVT_HANDLE hResults; EVT_HANDLE hResults;
bool isChannel;
bool ShouldIncludeEvent(const std::wstring& eventXml)
{
if (!isChannel)
{
return true; // Include all events if no filtering
}
// Check if the event contains PowerToys or CommandPalette
return (eventXml.find(L"PowerToys") != std::wstring::npos ||
eventXml.find(L"CommandPalette") != std::wstring::npos);
}
void PrintEvent(EVT_HANDLE hEvent) void PrintEvent(EVT_HANDLE hEvent)
{ {
@ -75,6 +105,17 @@ namespace
} }
} }
// Apply filtering if needed
std::wstring eventContent(pRenderedContent);
if (!ShouldIncludeEvent(eventContent))
{
if (pRenderedContent)
{
free(pRenderedContent);
}
return; // Skip this event
}
XmlDocumentEx doc; XmlDocumentEx doc;
doc.LoadXml(pRenderedContent); doc.LoadXml(pRenderedContent);
std::wstring formattedXml = L""; std::wstring formattedXml = L"";
@ -130,17 +171,27 @@ namespace
} }
public: public:
EventViewerReporter(const std::filesystem::path& tmpDir, std::wstring processName) EventViewerReporter(const std::filesystem::path& tmpDir, std::wstring queryName, std::wstring fileName, bool isChannel)
:isChannel(isChannel)
{ {
auto query = GetQuery(processName); std::wstring query = L"";
if (isChannel)
{
query = GetQueryByChannel(queryName);
}
else
{
query = GetQuery(queryName);
}
auto reportPath = tmpDir; auto reportPath = tmpDir;
reportPath.append(L"EventViewer-" + processName + L".xml"); reportPath.append(L"EventViewer-" + fileName + L".xml");
report = std::wofstream(reportPath); report = std::wofstream(reportPath);
hResults = EvtQuery(NULL, NULL, GetQuery(processName).c_str(), EvtQueryChannelPath); hResults = EvtQuery(NULL, NULL, query.c_str(), EvtQueryChannelPath);
if (NULL == hResults) if (NULL == hResults)
{ {
report << "Failed to report info for " << processName << ". " << get_last_error_or_default(GetLastError()) << std::endl; report << "Failed to report info for " << queryName << ". " << get_last_error_or_default(GetLastError()) << std::endl;
return; return;
} }
} }
@ -175,6 +226,11 @@ void EventViewer::ReportEventViewerInfo(const std::filesystem::path& tmpDir)
{ {
for (auto& process : processes) for (auto& process : processes)
{ {
EventViewerReporter(tmpDir, process).Report(); EventViewerReporter(tmpDir, process, process, false).Report();
} }
} }
void EventViewer::ReportAppXDeploymentLogs(const std::filesystem::path& tmpDir)
{
EventViewerReporter(tmpDir, L"Microsoft-Windows-AppXDeploymentServer/Operational", L"AppXDeploymentServerEventLog", true).Report();
}

View File

@ -4,4 +4,5 @@
namespace EventViewer namespace EventViewer
{ {
void ReportEventViewerInfo(const std::filesystem::path& tmpDir); void ReportEventViewerInfo(const std::filesystem::path& tmpDir);
void ReportAppXDeploymentLogs(const std::filesystem::path& tmpDir);
} }

View File

@ -381,6 +381,9 @@ int wmain(int argc, wchar_t* argv[], wchar_t*)
// Write event viewer logs info to the temporary folder // Write event viewer logs info to the temporary folder
EventViewer::ReportEventViewerInfo(reportDir); EventViewer::ReportEventViewerInfo(reportDir);
// Write AppXDeployment-Server event logs to the temporary folder
EventViewer::ReportAppXDeploymentLogs(reportDir);
ReportInstallerLogs(tempDir, reportDir); ReportInstallerLogs(tempDir, reportDir);
ReportInstalledContextMenuPackages(reportDir); ReportInstalledContextMenuPackages(reportDir);