project-system icon indicating copy to clipboard operation
project-system copied to clipboard

Improve the file share story

Open asbjornu opened this issue 9 years ago • 7 comments

There are many reasons for wanting to have your source code on a file share instead of on a local drive. I'm for instance using Windows inside of Parallels while hosting the source code on my Mac so I get tight integration with the OS X terminal for Git command line and all that jazz.

Having the source code Visual Studio is loading on a file share are problematic for quite a few reasons, some of which are way out of scope for the Roslyn Project System, but I thought I'd mention them anyway:

  1. I need to run Visual Studio with elevated permissions (as the Administrator) to have it configure IIS and such. Since I have a habit of double-clicking on .sln files in Windows Explorer, I needed to get Visual Studio 2015 to do this by default, by:
    1. Configuring devenv.exe to always run as an administrator. This made Visual Studio launch with a devenv.exe solution when, which forced me to:
    2. Also configure VSLauncher.exe to always run as an administrator. Light-years from intuitive, but it works.
  2. Since Visual Studio needs to be run with elevated permissions, the drives that are automatically mapped up by Parallels for my user, need to be manually mapped up by a login script with net use since even thought I do /persistent:yes, they are gone on every login.
  3. To have Visual Studio "trust" the network share, I've had to disable the "Warn user when the project location is not trusted" checkbox in Visual Studio, use caspol to grant permissions to the network share as well as grant permissions to the local intranet code group. I think I had to do caspol for different versions of .NET as well, but I don't remember the exact details. Again, light-years from intuitive, but it seems to work.
  4. When Visual Studio has loaded a solution on a network share, it is much less attentive to file changes that have happened outside of Visual Studio, such as a git checkout command executed in OS X.

As I wrote, some of these problems can't be attributed to the project system and are thus out of scope for this repository, but I just wanted to mention the whole story so you (as Microsoft) can understand just how much friction is involved here.

The probably worst thing is that I have to search for how to do each and every of the above steps each time I install Windows and/or Visual Studio, because it seems to be a variation on all of the above for each version of both Visual Studio and Windows. The steps are in any case so complicated to perform that I don't have enough cognitive capacity to remember between each time I reinstall, which I thankfully don't do very often (which of course affects my memory as well).

This relates to #169 in some ways, but I think the network share story requires its own user story, so here we are.

If you can improve on this in any way, you would add years to my expected lifespan for sure. If you can't, then at least now I have the required steps written down, so I can hopefully come back to this issue in the future to remind myself just how I did all of this. Thanks!

asbjornu avatar Jun 01 '16 06:06 asbjornu

I'm not sure this is the right issue to piggy-back, but here it goes... Let me know if this deserves a separate issue, or if it should be moved to the CLI repo or something.

Just like @asbjornu, I have code shared between macOS and Windows, using Parallels. When dealing with project.json, file shares and Visual Studio, the dependency resolution falls over.

If you change project.json and kick off a NuGet restore (this will mostly happen automatically), it'll claim that it failed to restore some (or all) packages. This clearly isn't true, as you can easily do a dotnet restore on the command line, and it resolves everything perfectly fine.

If you change project.json again and let it restore the packages, it'll successfully restore the packages from the previous edit, but fail for the latest changes you made. It's as if the Visual Studio restore is picking up the project.lock.json file form the previous restore.

I've had to move all projects dealing with project.json (quite a few) to the local disk on the VM in order for the VS tooling to work properly.

Steps to reproduce

  1. Create a project.json-based project on a file share/UNC path
  2. Open the project in VS
  3. Let VS restore the packages
  4. Observe that the restore failed
  5. Make a whitespace change to the project.json file
  6. Save project.json
  7. Let VS restore the packages (again)
  8. Observe that the restore succeeded

khellang avatar Oct 10 '16 12:10 khellang

Another annoying thing related to this is that the "Open Command Prompt" context menu provided by the Productivity Power Tools extension (also provided by Microsoft) fails to open a command prompt on the folder of the selected solution folder, due to the following error message:

'\\Mac\Home\Dev\Project'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported.  Defaulting to Windows directory.

To add insult to injury, the opened command prompt does not have the share mapped, so I have to type net use Y: \\Mac\Home and then cd /d Y:\Dev\Project just to be able to use the prompt for anything useful, making the whole feature useless. Again, not related to the project system, but one of many annoyances of having the source code reside on a network share.

Another issue not mentioned above is that IIS needs to use the full UNC path in its web applications in order to get access to the web.config file, since the file share isn't NTFS (and thus it's impossible to grant IUSR or anything else explicit access to the path). This causes all sorts of compatibility problems within the web applications themselves, as they are most likely not written to support UNC paths at all.

Fun!

asbjornu avatar Oct 10 '16 13:10 asbjornu

And now I encountered another problem related to working with file shares and .NET: When running a console application in an unelevated cmd.exe with a file share (mapped drive) as its working directory, the application blows up with the following exception:

System.Configuration.ConfigurationErrorsException: Error creating the Web Proxy specified in the 'system.net/defaultProxy' configuration section. ---> System.Net.Sockets.SocketException: An invalid argument was supplied
   at System.Net.SafeCloseSocketAndEvent.CreateWSASocketWithEvent(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType, Boolean autoReset, Boolean signaled)
   at System.Net.NetworkAddressChangePolled..ctor()
   at System.Net.AutoWebProxyScriptEngine.AutoDetector.Initialize()
   at System.Net.AutoWebProxyScriptEngine.AutoDetector.get_CurrentAutoDetector()
   at System.Net.AutoWebProxyScriptEngine..ctor(WebProxy proxy, Boolean useRegistry)
   at System.Net.WebProxy.UnsafeUpdateFromRegistry()
   at System.Net.WebProxy..ctor(Boolean enableAutoproxy)
   at System.Net.Configuration.DefaultProxySectionInternal..ctor(DefaultProxySection section)
   at System.Net.Configuration.DefaultProxySectionInternal.GetSection()
   --- End of inner exception stack trace ---
   at System.Net.Configuration.DefaultProxySectionInternal.GetSection()
   at System.Net.WebRequest.get_InternalDefaultWebProxy()
   at System.Net.HttpWebRequest..ctor(Uri uri, ServicePoint servicePoint)
   at System.Net.HttpWebRequest..ctor(Uri uri, Boolean returnResponseOnFailureStatusCode, String connectionGroupName, Action`1 resendRequestContent)
   at System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(HttpRequestMessage request)
   at System.Net.Http.HttpClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Pomona.Common.RequestDispatcher.<SendHttpRequestAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Pomona.Common.RequestDispatcher.<SendRequestInnerAsync>d__7.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Pomona.Common.RequestDispatcher.<SendRequestAsync>d__12.MoveNext()

An HTTP request is being made by the console application, which seemingly requires loading of proxy settings, which for some reason are out of reach from an application run with unelevated privileges with a file share as the working directory.

If I do cd /d C:\Windows before exeucting the console application, it works. It also works if I open up a cmd.exe with administrative privileges. It also works if I run the console application directly from an elevated Visual Studio instance. But the combination of unelevated cmd.exe and a file share as a working directory, makes the application fail with the above exception.

Yikes!

asbjornu avatar Oct 11 '16 10:10 asbjornu

@asbjornu Can you file this over on http://github.com/dotnet/corefx?

davkean avatar Oct 11 '16 17:10 davkean

@davkean: Sure! Thanks for stopping by. 😃 Should I report the whole issue, parts of it, a separate issue per part, or what?

asbjornu avatar Oct 12 '16 00:10 asbjornu

Just the last issue that you reported. I'm trying to figure out the best to way to track the other issues - it's really a cross-VS issue that covers lots of individual teams. I'll need to break up them up into bugs internally.

davkean avatar Oct 12 '16 00:10 davkean

@davkean: Thanks, done.

asbjornu avatar Oct 12 '16 08:10 asbjornu