1- using Microsoft . VisualStudio . ProjectSystem ;
1+ using EnvDTE ;
2+ using Microsoft . VisualStudio . ProjectSystem ;
23using Microsoft . VisualStudio . ProjectSystem . Debug ;
34using Microsoft . VisualStudio . ProjectSystem . Properties ;
45using SmartCmdArgs . DataSerialization ;
1920// As such, ensuring compatibility requires knowledge of the version Visual Studio redirects to, which varies
2021// by Visual Studio installation version.
2122
22- namespace SmartCmdArgs . Helper
23+ namespace SmartCmdArgs . Services
2324{
24- public static class CpsProjectSupport
25+ public interface ICpsProjectConfigService
2526 {
26- private static bool TryGetProjectServices ( EnvDTE . Project project , out IUnconfiguredProjectServices unconfiguredProjectServices , out IProjectServices projectServices )
27+ string GetActiveLaunchProfileName ( Project project ) ;
28+ void GetItemsFromConfig ( Project project , List < CmdItemJson > allArgs , bool includeArgs , bool includeEnvVars , bool includeWorkDir , bool includeLaunchApp ) ;
29+ IEnumerable < string > GetLaunchProfileNames ( Project project ) ;
30+ IDisposable ListenToLaunchProfileChanges ( Project project , Action listener ) ;
31+ void SetActiveLaunchProfileByName ( Project project , string profileName ) ;
32+ void SetActiveLaunchProfileToVirtualProfile ( Project project ) ;
33+ void SetConfig ( Project project , string arguments , IDictionary < string , string > envVars , string workDir , string launchApp ) ;
34+ }
35+
36+ public class CpsProjectConfigService : ICpsProjectConfigService
37+ {
38+ public static string VirtualProfileName = "Smart CLI Args" ;
39+
40+ private readonly IOptionsSettingsService optionsSettingsService ;
41+
42+ public CpsProjectConfigService (
43+ IOptionsSettingsService optionsSettingsService )
44+ {
45+ this . optionsSettingsService = optionsSettingsService ;
46+ }
47+
48+ private bool TryGetProjectServices ( EnvDTE . Project project , out IUnconfiguredProjectServices unconfiguredProjectServices , out IProjectServices projectServices )
2749 {
2850 IVsBrowseObjectContext context = project as IVsBrowseObjectContext ;
2951 if ( context == null && project != null )
@@ -55,7 +77,7 @@ private static bool TryGetProjectServices(EnvDTE.Project project, out IUnconfigu
5577 }
5678 }
5779
58- public static string GetActiveLaunchProfileName ( EnvDTE . Project project )
80+ public string GetActiveLaunchProfileName ( EnvDTE . Project project )
5981 {
6082 if ( TryGetProjectServices ( project , out IUnconfiguredProjectServices unconfiguredProjectServices , out IProjectServices projectServices ) )
6183 {
@@ -65,7 +87,21 @@ public static string GetActiveLaunchProfileName(EnvDTE.Project project)
6587 return null ;
6688 }
6789
68- public static IEnumerable < string > GetLaunchProfileNames ( EnvDTE . Project project )
90+ public void SetActiveLaunchProfileByName ( EnvDTE . Project project , string profileName )
91+ {
92+ if ( TryGetProjectServices ( project , out IUnconfiguredProjectServices unconfiguredProjectServices , out IProjectServices projectServices ) )
93+ {
94+ var launchSettingsProvider = unconfiguredProjectServices . ExportProvider . GetExportedValue < ILaunchSettingsProvider > ( ) ;
95+ projectServices . ThreadingPolicy . ExecuteSynchronously ( async ( ) =>
96+ {
97+ await launchSettingsProvider . SetActiveProfileAsync ( profileName ) ;
98+ } ) ;
99+ }
100+ }
101+
102+ public void SetActiveLaunchProfileToVirtualProfile ( EnvDTE . Project project ) => SetActiveLaunchProfileByName ( project , VirtualProfileName ) ;
103+
104+ public IEnumerable < string > GetLaunchProfileNames ( EnvDTE . Project project )
69105 {
70106 if ( TryGetProjectServices ( project , out IUnconfiguredProjectServices unconfiguredProjectServices , out IProjectServices projectServices ) )
71107 {
@@ -75,10 +111,11 @@ public static IEnumerable<string> GetLaunchProfileNames(EnvDTE.Project project)
75111 return null ;
76112 }
77113
78- public static IDisposable ListenToLaunchProfileChanges ( EnvDTE . Project project , Action listener )
114+ public IDisposable ListenToLaunchProfileChanges ( EnvDTE . Project project , Action listener )
79115 {
80116 if ( TryGetProjectServices ( project , out IUnconfiguredProjectServices unconfiguredProjectServices , out IProjectServices projectServices ) )
81117 {
118+
82119 var launchSettingsProvider = unconfiguredProjectServices . ExportProvider . GetExportedValue < ILaunchSettingsProvider > ( ) ;
83120
84121 if ( launchSettingsProvider == null )
@@ -92,20 +129,29 @@ public static IDisposable ListenToLaunchProfileChanges(EnvDTE.Project project, A
92129 return null ;
93130 }
94131
95- public static void SetCpsProjectConfig ( EnvDTE . Project project , string arguments , IDictionary < string , string > envVars , string workDir , string launchApp )
132+ public void SetConfig ( EnvDTE . Project project , string arguments , IDictionary < string , string > envVars , string workDir , string launchApp )
96133 {
97134 IUnconfiguredProjectServices unconfiguredProjectServices ;
98135 IProjectServices projectServices ;
99136
100137 if ( TryGetProjectServices ( project , out unconfiguredProjectServices , out projectServices ) )
101138 {
102139 var launchSettingsProvider = unconfiguredProjectServices . ExportProvider . GetExportedValue < ILaunchSettingsProvider > ( ) ;
103- var activeLaunchProfile = launchSettingsProvider ? . ActiveProfile ;
140+ ILaunchProfile baseLaunchProfile = null ;
141+ if ( optionsSettingsService . UseCpsVirtualProfile )
142+ {
143+ baseLaunchProfile = launchSettingsProvider . CurrentSnapshot . Profiles . FirstOrDefault ( x => x . Name == VirtualProfileName ) ;
144+ }
104145
105- if ( activeLaunchProfile == null )
146+ if ( baseLaunchProfile == null )
147+ {
148+ baseLaunchProfile = launchSettingsProvider ? . ActiveProfile ;
149+ }
150+
151+ if ( baseLaunchProfile == null )
106152 return ;
107153
108- WritableLaunchProfile writableLaunchProfile = new WritableLaunchProfile ( activeLaunchProfile ) ;
154+ WritableLaunchProfile writableLaunchProfile = new WritableLaunchProfile ( baseLaunchProfile ) ;
109155
110156 if ( arguments != null )
111157 writableLaunchProfile . CommandLineArgs = arguments ;
@@ -119,30 +165,31 @@ public static void SetCpsProjectConfig(EnvDTE.Project project, string arguments,
119165 if ( launchApp != null )
120166 writableLaunchProfile . CommandName = launchApp ;
121167
122- // Does not work on VS2015, which should be okay ...
123- // We don't hold references for VS2015, where the interface is called IThreadHandling
124- IProjectThreadingService projectThreadingService = projectServices . ThreadingPolicy ;
125- projectThreadingService . ExecuteSynchronously ( ( ) =>
168+ if ( optionsSettingsService . UseCpsVirtualProfile )
169+ {
170+ writableLaunchProfile . Name = VirtualProfileName ;
171+ writableLaunchProfile . DoNotPersist = true ;
172+ }
173+
174+ projectServices . ThreadingPolicy . ExecuteSynchronously ( ( ) =>
126175 {
127176 return launchSettingsProvider . AddOrUpdateProfileAsync ( writableLaunchProfile , addToFront : false ) ;
128177 } ) ;
129178 }
130179 }
131180
132- public static List < CmdItemJson > GetCpsProjectAllArguments ( EnvDTE . Project project , bool includeArgs , bool includeEnvVars , bool includeWorkDir , bool includeLaunchApp )
181+ public void GetItemsFromConfig ( EnvDTE . Project project , List < CmdItemJson > allArgs , bool includeArgs , bool includeEnvVars , bool includeWorkDir , bool includeLaunchApp )
133182 {
134183 IUnconfiguredProjectServices unconfiguredProjectServices ;
135184 IProjectServices projectServices ;
136185
137- var result = new List < CmdItemJson > ( ) ;
138-
139186 if ( TryGetProjectServices ( project , out unconfiguredProjectServices , out projectServices ) )
140187 {
141188 var launchSettingsProvider = unconfiguredProjectServices . ExportProvider . GetExportedValue < ILaunchSettingsProvider > ( ) ;
142189 var launchProfiles = launchSettingsProvider ? . CurrentSnapshot ? . Profiles ;
143190
144191 if ( launchProfiles == null )
145- return result ;
192+ return ;
146193
147194 foreach ( var profile in launchProfiles )
148195 {
@@ -173,17 +220,19 @@ public static List<CmdItemJson> GetCpsProjectAllArguments(EnvDTE.Project project
173220
174221 if ( profileGrp . Items . Count > 0 )
175222 {
176- result . Add ( profileGrp ) ;
223+ allArgs . Add ( profileGrp ) ;
177224 }
178225 }
179226 }
180-
181- return result ;
182227 }
183228 }
184229
185230 class WritableLaunchProfile : ILaunchProfile
231+ #if VS17
232+ , IPersistOption
233+ #endif
186234 {
235+ // ILaunchProfile
187236 public string Name { set ; get ; }
188237 public string CommandName { set ; get ; }
189238 public string ExecutablePath { set ; get ; }
@@ -194,8 +243,12 @@ class WritableLaunchProfile : ILaunchProfile
194243 public ImmutableDictionary < string , string > EnvironmentVariables { set ; get ; }
195244 public ImmutableDictionary < string , object > OtherSettings { set ; get ; }
196245
246+ // IPersistOption
247+ public bool DoNotPersist { get ; set ; }
248+
197249 public WritableLaunchProfile ( ILaunchProfile launchProfile )
198250 {
251+ // ILaunchProfile
199252 Name = launchProfile . Name ;
200253 ExecutablePath = launchProfile . ExecutablePath ;
201254 CommandName = launchProfile . CommandName ;
@@ -205,6 +258,13 @@ public WritableLaunchProfile(ILaunchProfile launchProfile)
205258 LaunchUrl = launchProfile . LaunchUrl ;
206259 EnvironmentVariables = launchProfile . EnvironmentVariables ;
207260 OtherSettings = launchProfile . OtherSettings ;
261+ #if VS17
262+ if ( launchProfile is IPersistOption persistOptionLaunchProfile )
263+ {
264+ // IPersistOption
265+ DoNotPersist = persistOptionLaunchProfile . DoNotPersist ;
266+ }
267+ #endif
208268 }
209269 }
210270}
0 commit comments