Based on Sergey Vlasov's comment, i created a VSIX project using Dynamically add menu items
for test in VS2022.It can be able to add a new/custom button to that context menu BUT ONLY for the "xyz" file type,for example. Please check the following steps.
This is the final run result:
Steps
1 Create a VSIX project named DynamicMenuItems.
2 When the project opens, add a custom command item template and name it FirstCommand.
After completing these two steps and you will see the project directory structure:

3 Specify a rule for when a button should be visible. In this example, the rule is that the button should be visible when the user right-clicks a .xyz file in Solution Explorer. We can express that in an attribute on the Package or AsyncPackage class like so:
[ProvideUIContextRule(PackageGuidString,
name: "Supported Files",
expression: "xyz",
termNames: new[] { "xyz" },
termValues: new[] { "HierSingleSelectionName:.xyz$" })]
See sample DynamicMenuItemsPackage.cs file about using the ProvideUXContextRule
attribute.
using System;
using System.ComponentModel.Design;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Task = System.Threading.Tasks.Task;
namespace DynamicMenuItems
{
/// <summary>
/// This is the class that implements the package exposed by this assembly.
/// </summary>
/// <remarks>
/// <para>
/// The minimum requirement for a class to be considered a valid package for Visual Studio
/// is to implement the IVsPackage interface and register itself with the shell.
/// This package uses the helper classes defined inside the Managed Package Framework (MPF)
/// to do it: it derives from the Package class that provides the implementation of the
/// IVsPackage interface and uses the registration attributes defined in the framework to
/// register itself and its components with the shell. These attributes tell the pkgdef creation
/// utility what data to put into .pkgdef file.
/// </para>
/// <para>
/// To get loaded into VS, the package must be referred by <Asset Type="Microsoft.VisualStudio.VsPackage" ...> in .vsixmanifest file.
/// </para>
/// </remarks>
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(DynamicMenuItemsPackage.PackageGuidString)]
[ProvideMenuResource("Menus.ctmenu", 1)]
[ProvideUIContextRule(PackageGuidString,
name: "Supported Files",
expression: "xyz",
termNames: new[] { "xyz" },
termValues: new[] { "HierSingleSelectionName:.xyz$" })]
public sealed class DynamicMenuItemsPackage : AsyncPackage
{
/// <summary>
/// DynamicMenuItemsPackage GUID string.
/// </summary>
public const string PackageGuidString = "f4dc9564-aebc-4d7a-826a-9d8c13e1542e";
#region Package Members
/// <summary>
/// Initialization of the package; this method is called right after the package is sited, so this is the place
/// where you can put all the initialization code that rely on services provided by VisualStudio.
/// </summary>
/// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param>
/// <param name="progress">A provider for progress updates.</param>
/// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns>
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
// When initialized asynchronously, the current thread may be a background thread at this point.
// Do any initialization that requires the UI thread after switching to the UI thread.
// Request any services while on the background thread
await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
await FirstCommand.InitializeAsync(this);
}
#endregion
}
}
4 Modify the menu group created for your action to make it an “Item node menu” command instead of a “Visual Studio Menu” command. Please refer to IDM_VS_CTXT_ITEMNODE
<Group guid="guidDynamicMenuItemsPackageCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
</Group>
5 Register a based on that rule in the .vsct.
<VisibilityConstraints>
<VisibilityItem guid="guidDynamicMenuItemsPackageCmdSet" id="FirstCommandId" context="PackageGuidString" />
</VisibilityConstraints>
6 Mark the button itself as dynamic visible.
<CommandFlag>DynamicVisibility</CommandFlag>
7 Customize your context menu name.
<Strings>
<ButtonText>My frist context menu</ButtonText>
</Strings>
8 Add UI Context guid that must match the one in DynamicMenuItemsPackage.cs.
<GuidSymbol name="PackageGuidString" value="{f4dc9564-aebc-4d7a-826a-9d8c13e1542e}" />
see sample DynamicMenuItemsPackage.vsct file:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Extern href="stdidcmd.h"/>
<Extern href="vsshlids.h"/>
<Commands package="guidDynamicMenuItemsPackage">
<Groups>
<Group guid="guidDynamicMenuItemsPackageCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_ITEMNODE"/>
</Group>
</Groups>
<Buttons>
<Button guid="guidDynamicMenuItemsPackageCmdSet" id="FirstCommandId" priority="0x0100" type="Button">
<Parent guid="guidDynamicMenuItemsPackageCmdSet" id="MyMenuGroup" />
<Icon guid="guidImages" id="bmpPic1" />
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>My frist context menu</ButtonText>
</Strings>
</Button>
</Buttons>
<Bitmaps>
<Bitmap guid="guidImages" href="Resources\FirstCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/>
</Bitmaps>
</Commands>
<VisibilityConstraints>
<VisibilityItem guid="guidDynamicMenuItemsPackageCmdSet" id="FirstCommandId" context="PackageGuidString" />
</VisibilityConstraints>
<Symbols>
<!-- This is the package guid. -->
<GuidSymbol name="guidDynamicMenuItemsPackage" value="{f4dc9564-aebc-4d7a-826a-9d8c13e1542e}" />
<!-- This is the UI Context guid that must match the one in MyPackage.cs -->
<GuidSymbol name="PackageGuidString" value="{f4dc9564-aebc-4d7a-826a-9d8c13e1542e}" />
<!-- This is the guid used to group the menu commands together -->
<GuidSymbol name="guidDynamicMenuItemsPackageCmdSet" value="{7ce2b30e-f5dc-4d0b-ac54-d731b2555fe7}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="FirstCommandId" value="0x0100" />
</GuidSymbol>
<GuidSymbol name="guidImages" value="{cf09af20-801f-4be3-b5d0-fabb0acb4e9d}" >
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
<IDSymbol name="bmpPicStrikethrough" value="6" />
</GuidSymbol>
</Symbols>
</CommandTable>
Note:You can refer to this guide:
https://github.com/microsoft/VSSDK-Extensibility-Samples/tree/master/VisibilityConstraints#lets-get-started