public async Task InitializeAsync()
        {
            await _threadHandling.Value.SwitchToUIThread();

            // Initialize our cache file
            string appDataFolder = await _shellUtilitiesHelper.Value.GetLocalAppDataFolderAsync(_vsShellService);

            if (appDataFolder != null)
            {
                _versionDataCacheFile = new RemoteCacheFile(Path.Combine(appDataFolder, s_versionDataFilename), s_versionCompatibilityDownloadFwlink,
                                                            TimeSpan.FromHours(s_cacheFileValidHours), _fileSystem.Value, _httpClient);
            }

            VisualStudioVersion = await _shellUtilitiesHelper.Value.GetVSVersionAsync(_vsAppIdService);

            _vsSolution = await _vsSolutionService.GetValueAsync();

            Verify.HResult(_vsSolution.AdviseSolutionEvents(this, out _solutionCookie));

            // Check to see if a solution is already open. If so we set _solutionOpened to true so that subsequent projects added to
            // this solution are processed.
            if (ErrorHandler.Succeeded(_vsSolution.GetProperty((int)__VSPROPID4.VSPROPID_IsSolutionFullyLoaded, out object isFullyLoaded)) &&
                isFullyLoaded is bool isFullyLoadedBool &&
                isFullyLoadedBool)
            {
                SolutionOpen = true;
                // do not block package initialization on this
                _threadHandling.Value.RunAndForget(async() =>
                {
                    // First make sure that the cache file exists
                    if (_versionDataCacheFile.ReadCacheFile() is null)
                    {
                        await _versionDataCacheFile.TryToUpdateCacheFileAsync();
                    }

                    // check if the project is compatible
                    await CheckCompatibilityAsync();
                }, unconfiguredProject: null);
            }
        }
Exemple #2
0
        /// <summary>
        /// Pings the server to download version compatibility information and stores this in a cached file in the users app data. If the cached file is
        /// less than 24 hours old, it uses that data. Otherwise it downloads from the server. If the download fails it will use the previously cached
        ///  file, or if that file doesn't not exist, it uses the data baked into this class
        /// </summary>
        private VersionCompatibilityData GetVersionCmpatibilityData()
        {
            // Do we need to update our cached data? Note that since the download could take a long time like tens of seconds we don't really want to
            // start showing messages to the user well after their project is opened and they are interacting with it. Thus we start a task to update the
            // file, so that the next time we come here, we have updated data.
            if (_curVersionCompatibilityData != null && _timeCurVersionDataLastUpdatedUtc.AddHours(CacheFileValidHours).IsLaterThan(DateTime.UtcNow))
            {
                return(_curVersionCompatibilityData);
            }

            try
            {
                // Try the cache file
                Dictionary <Version, VersionCompatibilityData> versionCompatData = GetCompabilityDataFromCacheFile();

                // See if the cache file needs refreshing and if so, kick off a task to do so
                if (_versionDataCacheFile != null && _versionDataCacheFile.CacheFileIsStale())
                {
                    Task noWait = _versionDataCacheFile.TryToUpdateCacheFileAsync(() =>
                    {
                        // Invalidate the in-memory cached data on success
                        _timeCurVersionDataLastUpdatedUtc = DateTime.MinValue;
                    });
                }

                if (versionCompatData != null)
                {
                    // First try to match exatly on our VS version and if that fails, match on just major, minor
                    if (versionCompatData.TryGetValue(_ourVSVersion, out VersionCompatibilityData compatData) || versionCompatData.TryGetValue(new Version(_ourVSVersion.Major, _ourVSVersion.Minor), out compatData))
                    {
                        // Now fix up missing data
                        if (string.IsNullOrEmpty(compatData.OpenSupportedMessage))
                        {
                            compatData.OpenSupportedMessage = VSResources.PartialSupportedDotNetCoreProject;
                        }

                        if (string.IsNullOrEmpty(compatData.OpenUnsupportedMessage))
                        {
                            compatData.OpenUnsupportedMessage = VSResources.NotSupportedDotNetCoreProject;
                        }

                        UpdateInMemoryCachedData(compatData);
                    }
                }
            }
            catch
            {
            }

            if (_curVersionCompatibilityData == null)
            {
                // Something failed or no remote file,  use the compatibility data we shipped with which does not have any warnings
                UpdateInMemoryCachedData(new VersionCompatibilityData()
                {
                    OpenSupportedMessage   = VSResources.PartialSupportedDotNetCoreProject,
                    OpenUnsupportedMessage = VSResources.NotSupportedDotNetCoreProject
                });
            }

            return(_curVersionCompatibilityData);
        }