@@ -22,9 +22,9 @@ namespace Microsoft.VisualStudio.FSharp.ProjectSystem
2222internal abstract class ProjectFactory : Microsoft . VisualStudio . Shell . Flavor . FlavoredProjectFactoryBase
2323, IVsProjectUpgradeViaFactory , IVsProjectUpgradeViaFactory4
2424
25- {
26- private Microsoft . VisualStudio . Shell . Package package ;
27- private System . IServiceProvider site ;
25+ {
26+ private Microsoft . VisualStudio . Shell . Package package ;
27+ private System . IServiceProvider site ;
2828
2929private Microsoft . Build . Evaluation . ProjectCollection buildEngine ;
3030private Microsoft . Build . Evaluation . Project buildProject ;
@@ -112,14 +112,56 @@ protected override void CreateProject(string fileName, string location, string n
112112}
113113}
114114
115+ // Solution properties
116+ IVsSolution solution = this . Site . GetService ( typeof ( SVsSolution ) ) as IVsSolution ;
117+ Debug . Assert ( solution != null , "Could not retrieve the solution service from the global service provider" ) ;
118+
119+ // We do not want to throw. If we cannot set the solution related constants we set them to empty string.
120+ string solutionDirectory , solutionPath , userOptionsFile ;
121+ solution . GetSolutionInfo ( out solutionDirectory , out solutionPath , out userOptionsFile ) ;
122+ if ( solutionDirectory == null )
123+ {
124+ solutionDirectory = String . Empty ;
125+ }
126+ if ( solutionPath == null )
127+ {
128+ solutionPath = String . Empty ;
129+ }
130+ string solutionFileName = ( solutionPath . Length == 0 ) ? String . Empty : Path . GetFileName ( solutionPath ) ;
131+ string solutionName = ( solutionPath . Length == 0 ) ? String . Empty : Path . GetFileNameWithoutExtension ( solutionPath ) ;
132+ var solutionExtension = Path . GetExtension ( solutionPath ) ;
133+
134+ // DevEnvDir property
135+ IVsShell shell = this . Site . GetService ( typeof ( SVsShell ) ) as IVsShell ;
136+ Debug . Assert ( shell != null , "Could not retrieve the IVsShell service from the global service provider" ) ;
137+ object installDirAsObject ;
138+
139+ // We do not want to throw. If we cannot set the solution related constants we set them to empty string.
140+ shell . GetProperty ( ( int ) __VSSPROPID . VSSPROPID_InstallDirectory , out installDirAsObject ) ;
141+ string installDir = ( ( string ) installDirAsObject ) ;
142+ if ( String . IsNullOrEmpty ( installDir ) )
143+ {
144+ installDir = String . Empty ;
145+ }
146+ else
147+ {
148+ // Ensure that we have trailing backslash as this is done for the langproj macros too.
149+ if ( installDir [ installDir . Length - 1 ] != Path . DirectorySeparatorChar )
150+ {
151+ installDir += Path . DirectorySeparatorChar ;
152+ }
153+ }
154+
115155// Get the list of GUIDs from the project/template
116156string guidsList = this . ProjectTypeGuids ( fileName ) ;
117157
118158// Launch the aggregate creation process (we should be called back on our IVsAggregatableProjectFactoryCorrected implementation)
119159IVsCreateAggregateProject aggregateProjectFactory = ( IVsCreateAggregateProject ) this . Site . GetService ( typeof ( SVsCreateAggregateProject ) ) ;
120160int hr = aggregateProjectFactory . CreateAggregateProject ( guidsList , fileName , location , name , flags , ref projectGuid , out project ) ;
121161if ( hr == VSConstants . E_ABORT )
162+ {
122163canceled = 1 ;
164+ }
123165ErrorHandler . ThrowOnFailure ( hr ) ;
124166
125167this . buildProject = null ;
@@ -146,6 +188,67 @@ protected override object PreCreateForOuter(IntPtr outerProjectIUnknown)
146188return node ;
147189}
148190
191+ internal Microsoft . Build . Evaluation . Project ReinitializeMsBuildProject ( string filename )
192+ {
193+ // Solution properties
194+ IVsSolution solution = this . Site . GetService ( typeof ( SVsSolution ) ) as IVsSolution ;
195+ Debug . Assert ( solution != null , "Could not retrieve the solution service from the global service provider" ) ;
196+
197+ // We do not want to throw.If we cannot set the solution related constants we set them to empty string.
198+ string solutionDirectory , solutionPath , userOptionsFile ;
199+ solution . GetSolutionInfo ( out solutionDirectory , out solutionPath , out userOptionsFile ) ;
200+ if ( solutionDirectory == null )
201+ {
202+ solutionDirectory = String . Empty ;
203+ }
204+ if ( solutionPath == null )
205+ {
206+ solutionPath = String . Empty ;
207+ }
208+ string solutionFileName = ( solutionPath . Length == 0 ) ? String . Empty : Path . GetFileName ( solutionPath ) ;
209+ string solutionName = ( solutionPath . Length == 0 ) ? String . Empty : Path . GetFileNameWithoutExtension ( solutionPath ) ;
210+ string solutionExtension = String . Empty ;
211+ if ( solutionPath . Length > 0 && Path . HasExtension ( solutionPath ) )
212+ {
213+ solutionExtension = Path . GetExtension ( solutionPath ) ;
214+ }
215+
216+ //DevEnvDir property
217+ IVsShell shell = this . Site . GetService ( typeof ( SVsShell ) ) as IVsShell ;
218+ Debug . Assert ( shell != null , "Could not retrieve the IVsShell service from the global service provider" ) ;
219+ object installDirAsObject ;
220+
221+ //We do not want to throw.If we cannot set the solution related constants we set them to empty string.
222+ shell . GetProperty ( ( int ) __VSSPROPID . VSSPROPID_InstallDirectory , out installDirAsObject ) ;
223+ string installDir = ( ( string ) installDirAsObject ) ;
224+ if ( String . IsNullOrEmpty ( installDir ) )
225+ {
226+ installDir = String . Empty ;
227+ }
228+ else
229+ {
230+ //Ensure that we have trailing backslash as this is done for the langproj macros too.
231+ if ( installDir [ installDir . Length - 1 ] != Path . DirectorySeparatorChar )
232+ {
233+ installDir += Path . DirectorySeparatorChar ;
234+ }
235+ }
236+
237+ var projectGlobalPropertiesThatAllProjectSystemsMustSet = new Dictionary < string , string > ( )
238+ {
239+ { GlobalProperty . SolutionDir . ToString ( ) , solutionDirectory } ,
240+ { GlobalProperty . SolutionPath . ToString ( ) , solutionPath } ,
241+ { GlobalProperty . SolutionFileName . ToString ( ) , solutionFileName } ,
242+ { GlobalProperty . SolutionName . ToString ( ) , solutionName } ,
243+ { GlobalProperty . SolutionExt . ToString ( ) , solutionExtension } ,
244+ { GlobalProperty . BuildingInsideVisualStudio . ToString ( ) , "true" } ,
245+ { GlobalProperty . Configuration . ToString ( ) , "" } ,
246+ { GlobalProperty . Platform . ToString ( ) , "" } ,
247+ { GlobalProperty . DevEnvDir . ToString ( ) , installDir }
248+ } ;
249+ return Utilities . ReinitializeMsBuildProject ( this . buildEngine , filename , projectGlobalPropertiesThatAllProjectSystemsMustSet , this . buildProject ) ;
250+ }
251+
149252/// <summary>
150253/// Retrives the list of project guids from the project file.
151254/// If you don't want your project to be flavorable, override
@@ -158,7 +261,7 @@ protected override string ProjectTypeGuids(string file)
158261{
159262// Load the project so we can extract the list of GUIDs
160263
161- this . buildProject = Utilities . ReinitializeMsBuildProject ( this . buildEngine , file , this . buildProject ) ;
264+ this . buildProject = this . ReinitializeMsBuildProject ( file ) ;
162265
163266// Retrieve the list of GUIDs, if it is not specify, make it our GUID
164267string guids = buildProject . GetPropertyValue ( ProjectFileConstants . ProjectTypeGuids ) ;
@@ -168,7 +271,6 @@ protected override string ProjectTypeGuids(string file)
168271return guids ;
169272}
170273
171-
172274private class ProjectInspector
173275{
174276private Microsoft . Build . Construction . ProjectRootElement xmlProj ;