string GetVSVersion() { var version = VisualStudio.Services.Dte.Version; var keyPath = String.Format(CultureInfo.InvariantCulture, "{0}\\{1}_Config\\SplashInfo", RegistryRootKey, version); try { using (var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(keyPath)) { var value = (string)key.GetValue(EnvVersionKey, String.Empty); if (!String.IsNullOrEmpty(value)) { return(value); } } var asm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName.StartsWith("Microsoft.VisualStudio.CommonIDE", StringComparison.OrdinalIgnoreCase)); if (asm != null) { return(asm.GetName().Version.ToString()); } } catch (Exception ex) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error getting the Visual Studio version '{0}'", ex)); } return(version); }
void EnsureAssemblyLoaded(Uri value) { try { var assemblyName = FindAssemblyNameFromPackUri(value); if (assemblyName == null) { VsOutputLogger.WriteLine(String.Format(CultureInfo.InvariantCulture, "Couldn't find assembly name in '{0}'.", value)); return; } var baseDir = Path.GetDirectoryName(GetType().Assembly.Location); var assemblyFile = Path.Combine(baseDir, assemblyName + ".dll"); if (assemblyDicts.ContainsKey(assemblyFile)) { return; } if (!File.Exists(assemblyFile)) { VsOutputLogger.WriteLine(String.Format(CultureInfo.InvariantCulture, "Couldn't find assembly at '{0}'.", assemblyFile)); return; } var assembly = Assembly.LoadFrom(assemblyFile); assemblyDicts.Add(assemblyFile, assembly); } catch (Exception e) { VsOutputLogger.WriteLine(String.Format(CultureInfo.InvariantCulture, "Error loading assembly for '{0}': {1}", value, e)); } }
static IEnumerable <ISimpleRepositoryModel> PokeTheRegistryForRepositoryList() { using (var key = OpenGitKey("Repositories")) { return(key.GetSubKeyNames().Select(x => { using (var subkey = key.OpenSubKey(x)) { try { var path = subkey?.GetValue("Path") as string; if (path != null) { return new SimpleRepositoryModel(path); } } catch (Exception ex) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error loading the repository from the registry '{0}'", ex)); } return null; } }) .Where(x => x != null) .ToList()); } }
static Assembly LoadAssemblyFromRunDir(object sender, ResolveEventArgs e) { try { var requestedName = e.Name.TrimSuffix(".dll", StringComparison.OrdinalIgnoreCase); var name = new AssemblyName(requestedName).Name; if (!ourAssemblies.Contains(name, StringComparer.OrdinalIgnoreCase)) { return(null); } var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var filename = Path.Combine(path, name + ".dll"); if (!File.Exists(filename)) { return(null); } return(Assembly.LoadFrom(filename)); } catch (Exception ex) { var log = string.Format(CultureInfo.CurrentCulture, "Error occurred loading {0} from {1}.{2}{3}{4}", e.Name, Assembly.GetExecutingAssembly().Location, Environment.NewLine, ex, Environment.NewLine); VsOutputLogger.Write(log); } return(null); }
static Assembly LoadAssemblyFromRunDir(object sender, ResolveEventArgs e) { try { var name = new AssemblyName(e.Name); if (!ourAssemblies.Contains(name.Name)) { return(null); } //if (name.Name.Equals("GitHub.TeamFoundation", StringComparison.Ordinal)) // name = new AssemblyName("GitHub.TeamFoundation." + VSVersion); var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var filename = Path.Combine(path, name.Name + ".dll"); if (!File.Exists(filename)) { return(null); } return(Assembly.LoadFrom(filename)); } catch (Exception ex) { var log = string.Format(CultureInfo.CurrentCulture, "Error occurred loading {0} from {1}.{2}{3}{4}", e.Name, Assembly.GetExecutingAssembly().Location, Environment.NewLine, ex, Environment.NewLine); VsOutputLogger.Write(log); } return(null); }
public static GitHubPane Activate() { var windowGuid = new Guid(GitHubPaneGuid); IVsWindowFrame frame; if (ErrorHandler.Failed(Services.UIShell.FindToolWindow((uint)__VSCREATETOOLWIN.CTW_fForceCreate, ref windowGuid, out frame))) { VsOutputLogger.WriteLine("Unable to find or create GitHubPane '" + GitHubPaneGuid + "'"); return(null); } if (ErrorHandler.Failed(frame.Show())) { VsOutputLogger.WriteLine("Unable to show GitHubPane '" + GitHubPaneGuid + "'"); return(null); } object docView = null; if (ErrorHandler.Failed(frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocView, out docView))) { VsOutputLogger.WriteLine("Unable to grab instance of GitHubPane '" + GitHubPaneGuid + "'"); return(null); } return(docView as GitHubPane); }
string GetVSVersion() { var version = typeof(Microsoft.VisualStudio.Shell.ActivityLog).Assembly.GetName().Version; var keyPath = String.Format(CultureInfo.InvariantCulture, "{0}\\{1}.{2}_Config\\SplashInfo", RegistryRootKey, version.Major, version.Minor); try { using (var key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(keyPath)) { var value = (string)key.GetValue(EnvVersionKey, String.Empty); if (!String.IsNullOrEmpty(value)) { return(value); } } // fallback to poking the CommonIDE assembly, which most closely follows the advertised version. var asm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName.StartsWith("Microsoft.VisualStudio.CommonIDE", StringComparison.OrdinalIgnoreCase)); if (asm != null) { return(asm.GetName().Version.ToString()); } } catch (Exception ex) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error getting the Visual Studio version '{0}'", ex)); } return(version.ToString()); }
void TrackState(object sender, PropertyChangedEventArgs e) { if (machine.PermittedTriggers.Contains(e.PropertyName)) { #if DEBUG VsOutputLogger.WriteLine(String.Format(CultureInfo.InvariantCulture, "{3} {0} title:{1} busy:{2}", e.PropertyName, ((ITeamExplorerSection)sender).Title, ((ITeamExplorerSection)sender).IsBusy, DateTime.Now)); #endif machine.Fire(e.PropertyName); } }
public string SetDefaultProjectPath(string path) { var old = String.Empty; try { var newProjectKey = Registry.CurrentUser.OpenSubKey(NewProjectDialogKeyPath, true) ?? Registry.CurrentUser.CreateSubKey(NewProjectDialogKeyPath); Debug.Assert(newProjectKey != null, string.Format(CultureInfo.CurrentCulture, "Could not open or create registry key '{0}'", NewProjectDialogKeyPath)); using (newProjectKey) { var mruKey = newProjectKey.OpenSubKey(MRUKeyPath, true) ?? Registry.CurrentUser.CreateSubKey(MRUKeyPath); Debug.Assert(mruKey != null, string.Format(CultureInfo.CurrentCulture, "Could not open or create registry key '{0}'", MRUKeyPath)); using (mruKey) { // is this already the default path? bail old = (string)mruKey.GetValue("Value0", string.Empty, RegistryValueOptions.DoNotExpandEnvironmentNames); if (String.Equals(path.TrimEnd('\\'), old.TrimEnd('\\'), StringComparison.CurrentCultureIgnoreCase)) { return(old); } // grab the existing list of recent paths, throwing away the last one var numEntries = (int)mruKey.GetValue("MaximumEntries", 5); var entries = new List <string>(numEntries); for (int i = 0; i < numEntries - 1; i++) { var val = (string)mruKey.GetValue("Value" + i, String.Empty, RegistryValueOptions.DoNotExpandEnvironmentNames); if (!String.IsNullOrEmpty(val)) { entries.Add(val); } } newProjectKey.SetValue("LastUsedNewProjectPath", path); mruKey.SetValue("Value0", path); // bump list of recent paths one entry down for (int i = 0; i < entries.Count; i++) { mruKey.SetValue("Value" + (i + 1), entries[i]); } } } } catch (Exception ex) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error setting the create project path in the registry '{0}'", ex)); } return(old); }
public IEnumerable <ILocalRepositoryModel> GetKnownRepositories() { try { return(RegistryHelper.PokeTheRegistryForRepositoryList()); } catch (Exception ex) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error loading the repository list from the registry '{0}'", ex)); return(Enumerable.Empty <ILocalRepositoryModel>()); } }
// The Default Repository Path that VS uses is hidden in an internal // service 'ISccSettingsService' registered in an internal service // 'ISccServiceHost' in an assembly with no public types that's // always loaded with VS if the git service provider is loaded public string GetLocalClonePathFromGitProvider() { string ret = string.Empty; try { ret = RegistryHelper.PokeTheRegistryForLocalClonePath(); } catch (Exception ex) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error loading the default cloning path from the registry '{0}'", ex)); } return(ret); }
public static bool Activate() { var windowGuid = new Guid(GitHubPaneGuid); IVsWindowFrame frame; if (ErrorHandler.Failed(Services.UIShell.FindToolWindow((uint)__VSCREATETOOLWIN.CTW_fForceCreate, ref windowGuid, out frame))) { VsOutputLogger.WriteLine("Unable to find or create GitHubPane '" + GitHubPaneGuid + "'"); return(false); } if (ErrorHandler.Failed(frame.Show())) { VsOutputLogger.WriteLine("Unable to show GitHubPane '" + GitHubPaneGuid + "'"); return(false); } return(true); }
void ShowNotification(ILocalRepositoryModel newrepo, string msg) { Guard.ArgumentNotNull(newrepo, nameof(newrepo)); var teServices = ServiceProvider.TryGetService <ITeamExplorerServices>(); teServices.ClearNotifications(); teServices.ShowMessage( msg, new RelayCommand(o => { var str = o.ToString(); /* the prefix is the action to perform: * u: launch browser with url * c: launch create new project dialog * o: launch open existing project dialog */ var prefix = str.Substring(0, 2); if (prefix == "u:") { OpenInBrowser(ServiceProvider.TryGetService <IVisualStudioBrowser>(), new Uri(str.Substring(2))); } else if (prefix == "o:") { if (ErrorHandler.Succeeded(ServiceProvider.GetSolution().OpenSolutionViaDlg(str.Substring(2), 1))) { ServiceProvider.TryGetService <ITeamExplorer>()?.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null); } } else if (prefix == "c:") { var vsGitServices = ServiceProvider.TryGetService <IVSGitServices>(); vsGitServices.SetDefaultProjectPath(newrepo.LocalPath); if (ErrorHandler.Succeeded(ServiceProvider.GetSolution().CreateNewProjectViaDlg(null, null, 0))) { ServiceProvider.TryGetService <ITeamExplorer>()?.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null); } } }) ); #if DEBUG VsOutputLogger.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0} Notification", DateTime.Now)); #endif }
void TryCleanupSolutionUserFiles(IOperatingSystem os, string repoPath, string slnName) { var vsTempPath = Path.Combine(repoPath, ".vs", slnName); try { // Clean up the dummy solution's subdirectory inside `.vs`. var vsTempDir = os.Directory.GetDirectory(vsTempPath); if (vsTempDir.Exists) { vsTempDir.Delete(true); } } catch (Exception e) { VsOutputLogger.WriteLine("Couldn't clean up {0}. {1}", vsTempPath, e); } }
/// <summary>Open a repository in Team Explorer</summary> /// <remarks> /// There doesn't appear to be a command that directly opens a target repo. /// Our workaround is to create, open and delete a solution in the repo directory. /// This triggers an event that causes the target repo to open. ;) /// </remarks> /// <param name="repoPath">The path to the repository to open</param> /// <returns>True if a transient solution was successfully created in target directory (which should trigger opening of repository).</returns> public bool TryOpenRepository(string repoPath) { var os = serviceProvider.TryGetService <IOperatingSystem>(); if (os == null) { VsOutputLogger.WriteLine("TryOpenRepository couldn't find IOperatingSystem service."); return(false); } var dte = serviceProvider.TryGetService <DTE>(); if (dte == null) { VsOutputLogger.WriteLine("TryOpenRepository couldn't find DTE service."); return(false); } var repoDir = os.Directory.GetDirectory(repoPath); if (!repoDir.Exists) { return(false); } bool solutionCreated = false; try { dte.Solution.Create(repoPath, TempSolutionName); solutionCreated = true; dte.Solution.Close(false); // Don't create a .sln file when we close. } catch (Exception e) { VsOutputLogger.WriteLine("Error opening repository. {0}", e); } finally { TryCleanupSolutionUserFiles(os, repoPath, TempSolutionName); } return(solutionCreated); }
async void UIContextChanged(bool active, bool refresh) { Debug.Assert(ServiceProvider != null, "UIContextChanged called before service provider is set"); if (ServiceProvider == null) { return; } if (active) { GitService = GitService ?? ServiceProvider.GetServiceSafe <IGitExt>(); if (ActiveRepo == null || refresh) { ActiveRepo = await System.Threading.Tasks.Task.Run(() => { var repos = GitService?.ActiveRepositories; // Looks like this might return null after a while, for some unknown reason // if it does, let's refresh the GitService instance in case something got wonky // and try again. See issue #23 if (repos == null) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error 2001: ActiveRepositories is null. GitService: '{0}'", GitService)); GitService = ServiceProvider?.GetServiceSafe <IGitExt>(); repos = GitService?.ActiveRepositories; if (repos == null) { VsOutputLogger.WriteLine(string.Format(CultureInfo.CurrentCulture, "Error 2002: ActiveRepositories is null. GitService: '{0}'", GitService)); } } return(repos?.FirstOrDefault()?.ToModel()); }); } } else { ActiveRepo = null; } }
/// <summary> /// Gets the currently active text view(s) from Visual Studio. /// </summary> /// <returns> /// Zero, one or two active <see cref="ITextView"/> objects. /// </returns> /// <remarks> /// This method will return a single text view for a normal code window, or a pair of text /// views if the currently active text view is a difference view in side by side mode, with /// the first item being the side that currently has focus. If there is no active text view, /// an empty collection will be returned. /// </remarks> protected IEnumerable <ITextView> GetCurrentTextViews() { var result = new List <ITextView>(); try { var serviceProvider = Package; var monitorSelection = (IVsMonitorSelection)serviceProvider.GetService(typeof(SVsShellMonitorSelection)); if (monitorSelection == null) { return(result); } object curDocument; if (ErrorHandler.Failed(monitorSelection.GetCurrentElementValue((uint)VSConstants.VSSELELEMID.SEID_DocumentFrame, out curDocument))) { return(result); } IVsWindowFrame frame = curDocument as IVsWindowFrame; if (frame == null) { return(result); } object docView = null; if (ErrorHandler.Failed(frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocView, out docView))) { return(result); } if (docView is IVsDifferenceCodeWindow) { var diffWindow = (IVsDifferenceCodeWindow)docView; switch (diffWindow.DifferenceViewer.ViewMode) { case DifferenceViewMode.Inline: result.Add(diffWindow.DifferenceViewer.InlineView); break; case DifferenceViewMode.SideBySide: switch (diffWindow.DifferenceViewer.ActiveViewType) { case DifferenceViewType.LeftView: result.Add(diffWindow.DifferenceViewer.LeftView); result.Add(diffWindow.DifferenceViewer.RightView); break; case DifferenceViewType.RightView: result.Add(diffWindow.DifferenceViewer.RightView); result.Add(diffWindow.DifferenceViewer.LeftView); break; } result.Add(diffWindow.DifferenceViewer.LeftView); break; case DifferenceViewMode.RightViewOnly: result.Add(diffWindow.DifferenceViewer.RightView); break; } } else if (docView is IVsCodeWindow) { IVsTextView textView; if (ErrorHandler.Failed(((IVsCodeWindow)docView).GetPrimaryView(out textView))) { return(result); } var model = (IComponentModel)serviceProvider.GetService(typeof(SComponentModel)); var adapterFactory = model.GetService <IVsEditorAdaptersFactoryService>(); var wpfTextView = adapterFactory.GetWpfTextView(textView); result.Add(wpfTextView); } } catch (Exception e) { VsOutputLogger.WriteLine("Exception in InlineCommentNavigationCommand.GetCurrentTextViews(): {0}", e); } return(result); }
static void ForgetWithLogging(Task task) { task.Catch(e => VsOutputLogger.WriteLine("Exception caught while executing background task: {0}", e)).Forget(); }
protected override void OnAttached() { base.OnAttached(); AssociatedObject.SelectionChanged += (s, e) => { if (e.AddedItems.Count > 0) { if (previousSelection == null) { previousSelection = AssociatedObject.SelectedItem; if (defaultValue == null) { var binding = GetBinding(); Debug.Assert(binding != null, "Cannot find ItemsSource binding. Did you configure it in the target Listbox?"); if (binding == null) { return; } defaultValue = PropertyPathHelper.GetValue(binding.ResolvedSource, binding.ResolvedSourcePropertyName); } var list = AssociatedObject.ItemsSource as IList; Debug.Assert(list != null, "ItemsSource data source is not an IList, cannot change it."); if (list == null) { return; } try { list.Insert(0, defaultValue); } catch (Exception ex) { #if DEBUG throw ex; #else VsOutputLogger.WriteLine(String.Format(CultureInfo.CurrentCulture, "Could not add default empty item to the bound ItemsSource data source - the collection does not allow insertion (or the type does not match). {0}", ex)); #endif } } else if (AssociatedObject.SelectedIndex == 0) { var list = AssociatedObject.ItemsSource as IList; Debug.Assert(list != null, "ItemsSource data source is not an IList, cannot change it."); Debug.Assert(list.Count > 0, "ItemsSource data source is empty, something went wrong."); if (list == null || list.Count == 0) { return; } if (list[0] == defaultValue) { list.RemoveAt(0); } } } if (e.RemovedItems.Count > 0) { if (e.RemovedItems[0] == defaultValue) { previousSelection = null; AssociatedObject.SelectedItem = null; } } }; }
void OnPropertyChange(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "IsVisible" && IsVisible && View == null) { View = new GitHubConnectContent { DataContext = this } } ; } async void UpdateRepositoryList(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { // if we're cloning or creating, only one repo will be added to the list // so we can handle just one new entry separately if (isCloning || isCreating) { var newrepo = e.NewItems.Cast <ISimpleRepositoryModel>().First(); SelectedRepository = newrepo; if (isCreating) { HandleCreatedRepo(newrepo); } else { HandleClonedRepo(newrepo); } var repo = await ApiFactory.Create(newrepo.CloneUrl).GetRepository(); newrepo.SetIcon(repo.Private, repo.Fork); } // looks like it's just a refresh with new stuff on the list, update the icons else { e.NewItems .Cast <ISimpleRepositoryModel>() .ForEach(async r => { if (Equals(Holder.ActiveRepo, r)) { SelectedRepository = r; } var repo = await ApiFactory.Create(r.CloneUrl).GetRepository(); r.SetIcon(repo.Private, repo.Fork); }); } } } void HandleCreatedRepo(ISimpleRepositoryModel newrepo) { var msg = string.Format(CultureInfo.CurrentUICulture, Constants.Notification_RepoCreated, newrepo.Name, newrepo.CloneUrl); msg += " " + string.Format(CultureInfo.CurrentUICulture, Constants.Notification_CreateNewProject, newrepo.LocalPath); ShowNotification(newrepo, msg); } void HandleClonedRepo(ISimpleRepositoryModel newrepo) { var msg = string.Format(CultureInfo.CurrentUICulture, Constants.Notification_RepoCloned, newrepo.Name, newrepo.CloneUrl); if (newrepo.HasCommits() && newrepo.MightContainSolution()) { msg += " " + string.Format(CultureInfo.CurrentUICulture, Constants.Notification_OpenProject, newrepo.LocalPath); } else { msg += " " + string.Format(CultureInfo.CurrentUICulture, Constants.Notification_CreateNewProject, newrepo.LocalPath); } ShowNotification(newrepo, msg); } void ShowNotification(ISimpleRepositoryModel newrepo, string msg) { var vsservices = ServiceProvider.GetExportedValue <IVSServices>(); vsservices.ClearNotifications(); vsservices.ShowMessage( msg, new RelayCommand(o => { var str = o.ToString(); /* the prefix is the action to perform: * u: launch browser with url * c: launch create new project dialog * o: launch open existing project dialog */ var prefix = str.Substring(0, 2); if (prefix == "u:") { OpenInBrowser(ServiceProvider.TryGetService <IVisualStudioBrowser>(), new Uri(str.Substring(2))); } else if (prefix == "o:") { if (ErrorHandler.Succeeded(ServiceProvider.GetSolution().OpenSolutionViaDlg(str.Substring(2), 1))) { ServiceProvider.TryGetService <ITeamExplorer>()?.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null); } } else if (prefix == "c:") { vsservices.SetDefaultProjectPath(newrepo.LocalPath); if (ErrorHandler.Succeeded(ServiceProvider.GetSolution().CreateNewProjectViaDlg(null, null, 0))) { ServiceProvider.TryGetService <ITeamExplorer>()?.NavigateToPage(new Guid(TeamExplorerPageIds.Home), null); } } }) ); #if DEBUG VsOutputLogger.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0} Notification", DateTime.Now)); #endif } void RefreshRepositories() { connectionManager.RefreshRepositories(); RaisePropertyChanged("Repositories"); // trigger a re-check of the visibility of the listview based on item count }