question

YannDuran-5311 avatar image
0 Votes"
YannDuran-5311 asked YannDuran-5311 commented

I can't seem to get MRU items from VS

I've tried 2 different ways of trying to get a list of VS's MRU items (projects and solutions) using code from this post: VSSDK Howto Fill MRUList into MRUListBox.

ExternalSettingsManager

var vsExePath = AppDomain.CurrentDomain.BaseDirectory + "devenv.exe";
var mruPath = @"MRUItems\{a9c4a31f-f9cb-47a9-abc0-49ce82d0b3ac}\Items";

using (ExternalSettingsManager ext = ExternalSettingsManager.CreateForApplication(vsExePath))
{
    var store = ext.GetReadOnlySettingsStore(SettingsScope.UserSettings);
    var mruList = new ArrayList();
    var names = store.GetPropertyNames(mruPath);

    foreach (string name in names)
    {
        string value = store.GetString(mruPath, name);
        string[] subValue = value.Split('|');
        mruList.Add(subValue[0]);
    }
 }

store.GetPropertyNames(mruPath) always throws a "Value does not fall within the expected range" error.


IVsMRUItemsStore.GetMRUItems(VSConstants.MruList.Projects, "")

var maxItems = 50;
var guid = VSConstants.MruList.Projects;
var mruItems = new string[maxItems];
var itemsStore = (IVsMRUItemsStore)await VS.Shell.GetMRUItemsStoreAsync();
var projectCount = itemsStore.GetMRUItems(ref guid, "", dwMaxResults: (uint)maxItems, rgbstrItems: mruItems);

projectCount is always zero, and there are no items in mruItems



Sadly I was unable to download the working sample project that @DylanZhu-MSFT had kindly uploaded. After I've been made to sign-in, the link returns:

We're sorry, but <my email address> can't be found in the microsoftapc-my.sharepoint.com directory. Please try again later, while we try to automatically fix this for you.

It looks like the sample project is hosted on Dylan's private Microsoft SharePoint site. I'd REALLY like to be able to try out that sample!

94015-image.png

Has anyone successfully been able to use either of these methods to get MRU items from VS? Or can anyone see a flaw in either my code or the original code here?

vs-extensions
image.png (93.9 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

DylanZhu-MSFT avatar image
0 Votes"
DylanZhu-MSFT answered

Hi YannDuran,

Before getting the mru list, you need to click Test Sub Command to trigger the event at the first time. After that the mru list will auto refresh when you go to Extensions > Test Menu > Sub Menu.

By the way, since the policy, we cannot share the sample through our onedrive at the moment, I paste the codes here:

     private TestCommand(AsyncPackage package, OleMenuCommandService commandService)
     {
         ....

         this.InitMRUMenu(commandService);
     }

     private int baseMRUID = (int)TopLevelMenuPackage.cmdidMRUList;
     private ArrayList mruList;

     private void InitializeMRUList()
     {
         if (null == this.mruList)
         {
             this.mruList = new ArrayList();
             if (null != this.mruList)
             {
                 string vsExePath = AppDomain.CurrentDomain.BaseDirectory + "devenv.exe";
                 string mruPath = @"MRUItems\{" + VSConstants.MruList.Projects + @"}\Items";

                 ExternalSettingsManager ext = ExternalSettingsManager.CreateForApplication(vsExePath);
                 SettingsStore store = ext.GetReadOnlySettingsStore(SettingsScope.UserSettings);
                 foreach (string name in store.GetPropertyNames(mruPath))
                 {
                     string value = store.GetString(mruPath, name);
                     string[] subValue = value.Split('|');
                     this.mruList.Add(subValue[0]);
                 }
             }
         }
     }

     private void InitMRUMenu(OleMenuCommandService mcs)
     {
         InitializeMRUList();
         for (int i = 0; i < this.mruList.Count; i++)
         {
             var cmdID = new CommandID(
                 new Guid(TopLevelMenuPackage.guidTopLevelMenuPackageCmdSet), this.baseMRUID + i);
             var mc = new OleMenuCommand(
                 new EventHandler(OnMRUExec), cmdID);
             mc.BeforeQueryStatus += new EventHandler(OnMRUQueryStatus);
             mcs.AddCommand(mc);
         }
     }

     private void OnMRUQueryStatus(object sender, EventArgs e)
     {
         OleMenuCommand menuCommand = sender as OleMenuCommand;
         if (null != menuCommand)
         {
             int MRUItemIndex = menuCommand.CommandID.ID - this.baseMRUID;
             if (MRUItemIndex >= 0 && MRUItemIndex < this.mruList.Count)
             {
                 menuCommand.Text = this.mruList[MRUItemIndex] as string;
             }
         }
     }

     private void OnMRUExec(object sender, EventArgs e)
     {
         var menuCommand = sender as OleMenuCommand;
         if (null != menuCommand)
         {
             int MRUItemIndex = menuCommand.CommandID.ID - this.baseMRUID;
             if (MRUItemIndex >= 0 && MRUItemIndex < this.mruList.Count)
             {
                 string selection = this.mruList[MRUItemIndex] as string;
                 for (int i = MRUItemIndex; i > 0; i--)
                 {
                     this.mruList[i] = this.mruList[i - 1];
                 }
                 this.mruList[0] = selection;
                 System.Windows.Forms.MessageBox.Show(
                     string.Format(CultureInfo.CurrentCulture,
                                   "Selected {0}", selection));
             }
         }
     }

Hope it could help you.

Best Regards,
Dylan

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

YannDuran-5311 avatar image
0 Votes"
YannDuran-5311 answered DylanZhu-MSFT commented

Thanks for you reply @DylanZhu-MSFT , but you clearly didn't read where I wrote that store.GetPropertyNames(mruPath) always throws a "Value does not fall within the expected range" error (line 23 in the code that you pasted here).

I'm the author of the Start Page+ extension. My current method of getting MRU items kind of works, but it gets its values from the registry, and the registry items do not always reflect what the new VS 2019 Start Window shows, so I was looking for a different method to get the MRU items consistently show the same items as those in the Start Window.

The code that I'm testing is exactly the same as what you've posted in lines 18-27. I know in theory your code should work, but for me line 23 always throws an error.

Could you please verify that your sample still works in VS 2019 16.9.4, and then add it as an attachment here in this thread so that I can step through those lines on my machine?

Thanks!










· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi @YannDuran-5311 , my visual studio is 16.9.4, and it could work. I can't upload it as attachment which doesn't support the zip file.
By the way, I found another way to get the MRU list, maybe it can help you: https://github.com/GrzegorzKozub/ClearRecent/blob/f8297376ca999fd3ef4c89fd5d2b0d6645d22b74/src/ClearRecent/Services/FileMenuRecents.cs#L51

0 Votes 0 ·
YannDuran-5311 avatar image
0 Votes"
YannDuran-5311 answered YannDuran-5311 commented

Again, I appreciate your reply. I had already found that repo. The method he uses only returns path strings, I need several of the properties contained in the registry, or in ApplicationPrivateSettings.xml.

I've bolded the properties that I need below.

{
        "Key": "c:\\lss\\start-page-plus\\start-page-plus.sln",
        "Value": {
            "LocalProperties": {
                "FullPath": "c:\\lss\\start-page-plus\\start-page-plus.sln",
                "Type": 0,**
                "SourceControl": null
            },
            "CodespaceProperties": null,
            "Remote": null,
            "IsFavorite": true,
            "LastAccessed": "2021-05-03T12:37:16.1096391+00:00",
            "IsLocal": true,
            "IsCodespace": false,
            "HasRemote": false,
            "IsSourceControlled": false
        }
}
· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Oops, the bold didn't work. The properties that I need are:

  • FullPath

  • Type

  • IsFavorite

  • LastAccessed


I was concentrating on getting the list of MRU items, but I really need to be able to save modified values back again as well.

TIA

0 Votes 0 ·