Ant-f/WorkingFilesList

Not all open files being shown in the list

Closed this issue · 11 comments

I've noticed this issue quite a lot when working with VS and Unity game engine. Not too sure what causes it. Possibly caused by the fact Unity changes the VS project from the outside? When I select a file that isn't shown in the list, it appears in the list again. Sometimes when I close a file, the list refreshes and shows everything again. VS 15.5.4, Unity 2018.1.2.

bug

Ant-f commented

I've not worked with a Unity project before; could you explain what you mean when you say Unity changes the VS project from the outside? Does it have an editor external to VS? Is VS always in focus (i.e. the active application) when the VS code-editor-window is opened?

Is there a specific type of file that always doesn't get added to Working Files List the first time, or only sometimes? Or is it a normal .cs files that sometimes gets added, and other times not?

I'm not too sure how Unity actually does things in that regard. It generates the Visual Studio project when you add or delete scripts in the Unity Editor. So yes, it's an external editor, VS isn't always in focus.

I found a consistent way to reproduce this issue is to create a new C# script in Unity, double click to open it, which re-focuses on Visual Studio (having configured Unity to use VS as default code editor of course). Working Files List shows only that new script and a few others (don't know why those specifically) in the list. When I then close the new file in VS, the list suddenly shows all open files again.

Ant-f commented

When you double click the script (causing Visual Studio to refocus) is it a new instance? If not, does it reload the VS solution?

You also mentioned that only the new script and a few others are in Working Files List. Do you mean that some of the items previously in the list have gone, or that many new code windows have opened in VS but of those only a few are initially shown in Working Files List?

When you double click the script in Unity, it simply opens that file in Visual Studio, within the project if VS is already open. Every time you create a new script in Unity it refreshes the project I think. Noticed it also does this when I delete a script in Unity, so I guess it happens every time Unity has to update the VS project.

And for the second thing: yes, a lot of the items that were previously in the list disappear but a few usually remain (plus the one you actually created & opened from Unity). I can't really see why those remain specifically.

I've made a desktop recording (and talked over it a bit) to show what happens:
2018-06-14 00-26-49.zip

Ant-f commented

Thanks for the recording. It's much easier to see what's going on.

It looks like when a new script is created in Unity, Unity somehow modifies/rewrites the .csproj/.sln file and VS unloads and reloads it. I suspect this because the whole Framework project disappears from Working Files List. When it reappears it is a different colour, suggesting it is a previously unopened project as far as Working Files List is concerned.

I've tried to recreate/simulate this by creating a VS solution, and then modifying a .csproj file within a text editor. When I refocus on VS (2017), I get a dialog asking whether I want to reload the solution; I noticed that this (the dialog popping up) doesn't happen in the recording. Do you have a setting/extension that auto-reloads changed .csproj project files? I can find a similar option, but it only applies to files, and changes to projects are always prompted for me.

Hm, I noticed this might be a feature for the Visual Studio Tools for Unity (which you can get through Visual Studio Installer as a component for VS). In the past people used to see that "reload project" prompt pop up all the time. At some point they added an auto-reload feature:
image
So I guess this might be the cause?
Edit: yeah it's the "Automatic project reloading" setting. If set to false, behaviour is the same as it used to be (with the "reload project" prompt) and then the Working Files List works as intended too. I guess the automatic reloading doesn't properly trigger refreshes in extensions, or something like that.

Ant-f commented

Am I right in saying that some .csproj files are dynamically generated by Unity? If so, and they differ from 'normal' .csproj files, would you be able to post a sample (just open it in a text editor and copy/paste the contents)? It can be a sample one with just one file reference.

Here's the csproj for the Framework project.
Framework.zip
I don't know how Unity generates the VS files exactly, but it makes sense that it creates the sln and csproj files. There's a Solution for the whole Unity project, and each Project in that Solution is generated either through Unity's special folders, or through Assembly Definition Files created by the user. "Framework" for example is all the scripts I have in the directories below one of those assembly definitions.

Ant-f commented

I've managed to recreate the issue, but it isn't as easy to fix as I would have hoped. Working Files List maintains synchronisation by listening to events such as when Visual Studio windows are created, and closed, for example. When a Unity project is overwritten, it is effectively removed from the solution and any of its open files are closed. Working Files List listens for these events, and behaves accordingly; that's why the file entries disappear.

Without Unity Automatic project reloading enabled, project files being removed have any open editor windows closed. When this setting is enabled however, the editor windows remain open even though events are sent to indicate that they have been closed. This creates a disparity between the editor windows actually open, and the files displayed by Working Files List. There are events available for projects being added, and files being loaded (but not when they have actually finished loading); this makes the latter unsuitable for knowing when to trigger a synchronisation.

I can however use the former, and add a small delay between the project being loaded before triggering a synchronisation; I've tried this and it seems to work. The delay would be to allow all files within the project to fully load. As there is no event to know when all files have been fully loaded, there is no guarantee that doing this will work 100% of the time, and may cause Working Files List to 'flicker' (depending on the duration of the delay). However, it should avoid the situation where you have to manually close a file in order for all files to display correctly.

I'm glad you've found the root of the issue, great job! Doesn't seem like it'll allow for a pretty solution but I'll take it. Let me know when it finds its way into a release.

Ant-f commented

This has been included in version 1.3. I've defaulted the delay to be 100ms, but it can be configured in the Options page. I don't work with Unity projects, so I don't know if there's a better value to default it to. If there is, let me know and I can change it in a future release.