@@ -155,11 +155,20 @@ public bool OpenSolutionOrProject(FileName fileName)
155155 }
156156 if ( ! CloseSolution ( allowCancel : true ) )
157157 return false ;
158- FileUtility . ObservedLoad ( OpenSolutionInternal , fileName ) ;
158+ FileUtility . ObservedLoad ( OpenSolutionOrProjectInternal , fileName ) ;
159159
160160 return currentSolution != null ;
161161 }
162162
163+ void OpenSolutionOrProjectInternal ( FileName fileName )
164+ {
165+ if ( fileName . HasExtension ( ".sln" ) ) {
166+ OpenSolutionInternal ( fileName ) ;
167+ } else {
168+ OpenProjectInternal ( fileName ) ;
169+ }
170+ }
171+
163172 void OpenSolutionInternal ( FileName fileName )
164173 {
165174 ISolution solution ;
@@ -182,6 +191,8 @@ public bool OpenSolution(FileName fileName)
182191
183192 public bool OpenSolution ( ISolution solution )
184193 {
194+ if ( solution == null )
195+ throw new ArgumentNullException ( "solution" ) ;
185196 if ( ! CloseSolution ( allowCancel : true ) )
186197 return false ;
187198 this . CurrentSolution = solution ;
@@ -191,9 +202,9 @@ public bool OpenSolution(ISolution solution)
191202
192203 void OnSolutionOpened ( ISolution solution )
193204 {
194- SolutionOpened ( this , new SolutionEventArgs ( solution ) ) ;
195205 foreach ( var project in solution . Projects )
196206 project . ProjectLoaded ( ) ;
207+ SolutionOpened ( this , new SolutionEventArgs ( solution ) ) ;
197208 SD . FileService . RecentOpen . AddRecentProject ( solution . FileName ) ;
198209 Project . Converter . UpgradeViewContent . ShowIfRequired ( solution ) ;
199210 foreach ( var project in solution . Projects . OfType < ErrorProject > ( ) ) {
@@ -205,77 +216,67 @@ void OnSolutionOpened(ISolution solution)
205216 }
206217 }
207218
208- /*
209- static void LoadProjectInternal(string fileName)
219+ void OpenProjectInternal ( FileName fileName )
210220 {
211221 if ( ! Path . IsPathRooted ( fileName ) )
212222 throw new ArgumentException ( "Path must be rooted!" ) ;
213- string solutionFile = Path.ChangeExtension(fileName, ".sln");
214- if (File.Exists(solutionFile)) {
215- LoadSolutionInternal(solutionFile);
216-
217- if (openSolution != null) {
218- bool found = false;
219- foreach (IProject p in openSolution.Projects) {
220- if (FileUtility.IsEqualFileName(fileName, p.FileName)) {
221- found = true;
222- break;
223- }
223+ FileName solutionFile = new FileName ( Path . ChangeExtension ( fileName , ".sln" ) ) ;
224+ ISolution solution = null ;
225+ bool solutionOpened = false ;
226+ // Use try-finally block to dispose the solution unless it is opened successfully.
227+ try {
228+ if ( SD . FileSystem . FileExists ( solutionFile ) ) {
229+ using ( var progress = AsynchronousWaitDialog . ShowWaitDialog ( "Loading Solution..." ) ) {
230+ solution = LoadSolutionFile ( solutionFile , progress ) ;
224231 }
225- if (found == false) {
226- var parseArgs = new[] { new StringTagPair("SolutionName", Path.GetFileName(solutionFile)), new StringTagPair("ProjectName", Path.GetFileName(fileName))};
227- int res = MessageService.ShowCustomDialog(MessageService.ProductName,
228- StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject}", parseArgs),
229- 0, 2,
230- StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject.AddProjectToSolution}", parseArgs),
231- StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject.CreateNewSolution}", parseArgs),
232- "${res:Global.IgnoreButtonText}");
233- if (res == 0) {
234- // Add project to solution
235- Commands.AddExistingProjectToSolution.AddProject((ISolutionItemNode)ProjectBrowserPad.Instance.SolutionNode, FileName.Create(fileName));
236- SaveSolution();
237- return;
238- } else if (res == 1) {
239- CloseSolution();
240- try {
241- File.Copy(solutionFile, Path.ChangeExtension(solutionFile, ".old.sln"), true);
242- } catch (IOException){}
243- } else {
244- // ignore, just open the solution
245- return;
232+ // If LoadSolutionFile() throws ProjectLoadException, let that be handled by the ObservedLoad.
233+
234+ if ( solution . Projects . Any ( p => p . FileName == fileName ) ) {
235+ // We can use the solution as-is
236+ OpenSolution ( solution ) ;
237+ solutionOpened = true ;
238+ return ;
239+ }
240+ // The solution does not contain the project, ask the user on how to proceed:
241+ var parseArgs = new [ ] { new StringTagPair ( "SolutionName" , Path . GetFileName ( solutionFile ) ) , new StringTagPair ( "ProjectName" , Path . GetFileName ( fileName ) ) } ;
242+ int res = MessageService . ShowCustomDialog ( MessageService . ProductName ,
243+ StringParser . Parse ( "${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject}" , parseArgs ) ,
244+ 0 , 2 ,
245+ StringParser . Parse ( "${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject.AddProjectToSolution}" , parseArgs ) ,
246+ StringParser . Parse ( "${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.SolutionDoesNotContainProject.CreateNewSolution}" , parseArgs ) ,
247+ "${res:Global.IgnoreButtonText}" ) ;
248+ if ( res == 0 ) {
249+ // Fall-through: the code below will add the project to the solution
250+ } else if ( res == 1 ) {
251+ // Create new solution: first make a backup of the old one
252+ try {
253+ File . Copy ( solutionFile , Path . ChangeExtension ( solutionFile , ".old.sln" ) , true ) ;
254+ } catch ( IOException ) {
246255 }
256+ // Replace solution with an empty one:
257+ solution . Dispose ( ) ;
258+ solution = CreateEmptySolutionFile ( solutionFile ) ;
259+ // Fall-through: the code below will add the project to the solution
247260 } else {
248- // opened solution instead and correctly found the project
261+ // ignore, just open the solution as-is
262+ OpenSolution ( solution ) ;
263+ solutionOpened = true ;
249264 return ;
250265 }
251266 } else {
252- // some problem during opening, abort
253- return ;
267+ // Solution does not already exist; create a new one
268+ solution = CreateEmptySolutionFile ( solutionFile ) ;
254269 }
270+ solution . AddExistingProject ( fileName ) ;
271+ solution . Save ( ) ;
272+ OpenSolution ( solution ) ;
273+ solutionOpened = true ;
274+ } finally {
275+ // Dispose the solution if it was not opened successfully
276+ if ( solution != null && ! solutionOpened )
277+ solution . Dispose ( ) ;
255278 }
256- ISolution solution = new Solution(new ProjectChangeWatcher(solutionFile));
257- solution.Name = Path.GetFileNameWithoutExtension(fileName);
258- IProjectBinding binding = ProjectBindingService.GetBindingPerProjectFile(fileName);
259- IProject project;
260- if (binding != null) {
261- project = ProjectBindingService.LoadProject(new ProjectLoadInformation(solution, FileName.Create(fileName), solution.Name));
262- if (project is UnknownProject) {
263- if (((UnknownProject)project).WarningDisplayedToUser == false) {
264- ((UnknownProject)project).ShowWarningMessageBox();
265- }
266- return;
267- }
268- } else {
269- MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.InvalidProjectOrCombine}", new StringTagPair("FileName", fileName)));
270- return;
271- }
272- solution.AddFolder(project);
273-
274- if (FileUtility.ObservedSave((NamedFileOperationDelegate)solution.Save, solutionFile) == FileOperationResult.OK) {
275- // only load when saved succesfully
276- LoadSolution(solutionFile);
277- }
278- }*/
279+ }
279280 #endregion
280281
281282 #region CloseSolution
@@ -374,7 +375,7 @@ void IProjectServiceRaiseEvents.RaiseProjectCreated(ProjectEventArgs e)
374375 {
375376 ProjectCreated ( this , e ) ;
376377 }
377-
378+
378379 void IProjectServiceRaiseEvents . RaiseSolutionCreated ( SolutionEventArgs e )
379380 {
380381 SolutionCreated ( this , e ) ;
@@ -384,13 +385,13 @@ void IProjectServiceRaiseEvents.RaiseProjectItemAdded(ProjectItemEventArgs e)
384385 {
385386 ProjectItemAdded ( this , e ) ;
386387 }
387-
388+
388389 void IProjectServiceRaiseEvents . RaiseProjectItemRemoved ( ProjectItemEventArgs e )
389390 {
390391 ProjectItemRemoved ( this , e ) ;
391392 }
392393 #endregion
393-
394+
394395 #region Project Bindings
395396 readonly IReadOnlyList < ProjectBindingDescriptor > projectBindings ;
396397
0 commit comments