-
Notifications
You must be signed in to change notification settings - Fork 112
Description
There is a common challenge when using Trace Parser locally for UDE environments: it only shows either system or custom metadata, not both at the same time. This forces users to repeatedly switch between folders using "File > select local metadata repo", which is inconvenient and slows down the workflow.
In https://www.yammer.com/dynamicsaxfeedbackprograms/threads/3407795405217792, @batetech describes the issue and shared a PowerShell script that creates a new folder (xxceTraceParserPackagesLocalDirectory) under %localappdata%\Microsoft\Dynamics365\RuntimeSymLinks\{yourConfig}\xxceTraceParserPackagesLocalDirectory using symbolic links to combine system and custom metadata. This allows Trace Parser to display the complete source code view for both, without duplicating data or using extra disk space.
The script is intended for local UDE environments. After running it, Trace Parser can be pointed to the new folder, and it will show both sets of code.
The script is to be integrated into d365fo.tools as a new command.
PowerShell script by @batetech
#Requires -RunAsAdministrator
<#
This script will create Symbolic Links for UDE environments for use in TraceParse
A folder will be created under "%localappdata%\Microsoft\Dynamics365\RuntimeSymLinks\{yourConfig}\xxceTraceParserPackagesLocalDirectory"
which contains all PackagesLocalDirectory and custom metadata, so that Trace Parser can display the correct source code.
In Trace Parser, after running this script, go to "File > select local metadata repo" and select the new xxceTraceParserPackagesLocalDirectory folder.
Change history:
2025-07-09 Brad Bateman - created
#>
$ErrorActionPreference = 'Stop';
#############################################
#<Params>
# Set $RuntimeSymLinksConfigPath to the path under "%localappdata%\Microsoft\Dynamics365\RuntimeSymLinks\{yourConfig}"
# By default, it will use the most recently modified config folder, or you can override the $RuntimeSymLinksConfigPath to a custom value.
$RuntimeSymLinksConfigPath = join-path "$($env:LOCALAPPDATA)" -ChildPath "Microsoft\Dynamics365\RuntimeSymLinks";
$configName = (gci "$RuntimeSymLinksConfigPath" | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1).Name
$RuntimeSymLinksConfigPath = Join-Path $RuntimeSymLinksConfigPath -ChildPath $configName
$debug = $true;
#</Params>
#############################################
$customMetadataSourcePath = Join-Path "$RuntimeSymLinksConfigPath" "ZZZZ__Metadata"
$systemMetadataSourcePath = Join-Path "$RuntimeSymLinksConfigPath" "PackagesLocalDirectory"
$targetRootPath = Join-Path "$RuntimeSymLinksConfigPath" "xxceTraceParserPackagesLocalDirectory"
$removeAOSDirIfExists = $true;
if(-not (Test-Path $RuntimeSymLinksConfigPath))
{
Write-Error "RuntimeSymLinksConfigPath folder not found: $RuntimeSymLinksConfigPath"
}
elseif($RuntimeSymLinksConfigPath -inotlike '*\Microsoft\Dynamics365\RuntimeSymLinks\*')
{
Write-Error "RuntimeSymLinksConfigPath doesn not contain expected path with RuntimeSymLinks: $RuntimeSymLinksConfigPath"
}
if(-not (Test-Path $targetRootPath))
{
New-Item $targetRootPath -ItemType Directory
}
if(-not (Test-Path $customMetadataSourcePath))
{
Write-Error "Custom metadata folder not found: $customMetadataSourcePath"
}
if(-not (Test-Path $systemMetadataSourcePath))
{
Write-Error "System metadata folder not found: $systemMetadataSourcePath"
}
$RepoModelFolders = Get-ChildItem $customMetadataSourcePath -Directory
$RepoModelFolders += Get-ChildItem $systemMetadataSourcePath -Directory
foreach ($ModelFolder in $RepoModelFolders)
{
$Target = $ModelFolder.FullName
$newPath = Join-Path "$targetRootPath" "$($ModelFolder.Name)"
if((Test-Path $newPath) -and $removeAOSDirIfExists)
{
Write-Warning "Removing dir $newPath"
if($debug -eq $false)
{
cmd /c rmdir "$newPath" | Out-Null
}
else
{
Write-Host ' Skipped because debug is enabled' -BackgroundColor Gray
}
}
Write-Host "Create symlink to $Target in $newPath"
if($debug -eq $false)
{
New-Item -ItemType SymbolicLink -Path "$targetRootPath" -Name "$($ModelFolder.Name)" -Value "$Target" | Out-Null
}
else
{
Write-Host ' Skipped because debug is enabled' -BackgroundColor Gray
}
}
Write-Host "Completed successfully for path: $targetRootPath" -BackgroundColor Green