$(ProjectDir)

Topics: Bugs
Mar 27, 2009 at 6:17 PM
The "New DocProject Wizard" is crashing with a "System.UriFormatException: Invalid URI: The format of the URI could not be determined." exception being logged in the Application Log.

I've narrowed it down to the "Output Directory" setting of my C++ dll project. If it contains the default value of "$(SolutionDir)$(ConfigurationName)" it works fine. However I have mine set to "$(ProjectDir)$(ConfigurationName)" and apparently DocProject cannot handle this. Our VS solution has mixed C++ and C# .dll's contained in it. Thus we are deliberatly separating the output of the two types for organization reasons.

I bug fix for this problem would be greatly appreciated.

Thx,
Cody

Mar 30, 2009 at 2:02 AM
Hi Cody,

Please check the Windows Application event log for events with DocProject as the source.  If you find a stack trace please post it here.

Thanks, 
Dave
Mar 30, 2009 at 3:21 PM

Here ya go:

An error occurred while running the New Project Wizard:

System.UriFormatException: Invalid URI: The format of the URI could not be determined.

   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)

   at System.Uri..ctor(String uriString)

   at DaveSexton.DocProject.VCProjectOutput.get_RelativeOutputPath()

   at DaveSexton.DocProject.VCProjectOutput.get_OutputPath()

   at DaveSexton.DocProject.VCProjectOutput.get_OutputFile()

   at DaveSexton.DocProject.ProjectFactory.IsSourceProject(IAnyProject project)

   at DaveSexton.DocProject.Wizards.ChooseSourcesStep.<get_SourceProjects>b__0(IAnyProject currentProject)

   at DaveSexton.DocProject.DocProjectEnvironment.<FindProjectsInternal>d__7.MoveNext()

   at DaveSexton.DocProject.MarshalByRefEnumerator`1.MoveNext()

   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)

   at DaveSexton.DocProject.Wizards.ChooseSourcesStep.get_SourceProjects()

   at DaveSexton.DocProject.Wizards.ChooseSourcesStep.get_Control()

   at DaveSexton.DocProject.Wizards.ChooseSourcesStep.GetUserInterface(WizardController controller, Boolean preloading)

   at DaveSexton.DocProject.Wizards.Foundation.WizardStep.GetUserInterfaceInternal(WizardController controller, Boolean preloading)

   at DaveSexton.DocProject.Wizards.Foundation.WizardController.<Start>b__0(WizardStep step)

   at DaveSexton.DocProject.Wizards.Foundation.WizardController.ForEachStep(Action`1 action)

   at DaveSexton.DocProject.Wizards.Foundation.WizardController.Start(Boolean moveToVisible)

   at DaveSexton.DocProject.Wizards.Foundation.WizardForm..ctor(String wizardName, WizardStep firstStep, WizardStep lastStep)

   at DaveSexton.DocProject.Wizards.DocProjectConfigurationWizard.Run(IDocProject project, EventHandler`1 errorHandler)

   at DaveSexton.DocProject.Wizards.VSWizard.ProjectFinishedGenerating(Project project)

From: davedev [mailto:notifications@codeplex.com]
Sent: Sunday, March 29, 2009 8:03 PM
To: Cody Gibson
Subject: Re: $(ProjectDir) [DocProject:51542]

From: davedev

Hi Cody,

Please check the Windows Application event log for events with DocProject as the source. If you find a stack trace please post it here.

Thanks,
Dave

Read the full discussion online.

To add a post to this discussion, reply to this email (DocProject@discussions.codeplex.com)

To start a new discussion for this project, email DocProject@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Mar 30, 2009 at 3:50 PM
Hi Cody,

Thanks for the info.

The problem is located in the MSBuildVCProjectOutput.cs file, found in the DaveSexton.DocProject library.  Specifically, the EvaluateMacro method does not have a case statement for the ProjectDir macro.  This is required because C++ doesn't seem to use standard MSBuild properties like other projects do.  Instead it uses like-named macros, so as far as I know I had to hard code macro evaluation rules even to get the vanilla configuration to work.

Here's what's available at the moment, taken straight from DocProject 1.11.0 source code:

MSBuildVCProjectOutput.cs

/// <summary>
/// See <a href="http://msdn2.microsoft.com/en-us/library/c02as0cs(VS.71).aspx">Macros for Build Commands and Properties</a> 
/// for more information.
/// </summary>
private bool EvaluateMacro(string macro, string name, out string value)
{
  switch (name)
  {
    case "ConfigurationName":
      value = project.Properties["Configuration"];
      break;
    case "PlatformName":
      value = project.Properties["Platform"];
      break;
    case "DevEnvDir":
      value = PathFormat.EnsureDirectory(project.Properties["DevEnvDir"]);
      break;
    case "SolutionDir":
      value = PathFormat.EnsureDirectory(Path.GetDirectoryName(project.Properties["SolutionPath"]));
      break;
    case "SolutionPath":
      value = project.Properties["SolutionPath"];
      break;
    case "SolutionName":
      value = Path.GetFileNameWithoutExtension(project.Properties["SolutionPath"]);
      break;
    case "SolutionFileName":
      value = Path.GetFileName(project.Properties["SolutionPath"]);
      break;
    case "SolutionExt":
      value = Path.GetExtension(project.Properties["SolutionPath"]);
      break;
    case "VSInstallDir":
      value = PathFormat.EnsureDirectory(project.Properties["VSInstallDir"]);
      break;
    case "VCInstallDir":
      value = PathFormat.EnsureDirectory(project.Properties["VCInstallDir"]);
      break;
    case "FrameworkDir":
      value = PathFormat.EnsureDirectory(project.Properties["FrameworkDir"]);
      break;
    case "FrameworkVersion":
      value = project.Properties["FrameworkVersion"];
      break;
    case "FrameworkSDKDir":
      value = PathFormat.EnsureDirectory(project.Properties["FrameworkSDKDir"]);
      break;
    default:
      value = null;
      return false;
  }
 
  return true;
}
<!--EndFragment-->
I'll look into supporting ProjectDir in the next release, but for now my only suggestion is to include it yourself and rebuild the source code.  To get started, see How To Use The Source Code.

What do you think about updating the default case to something like the following?  Do you think that this would make sense for a C++ project?

default:
  value = project.Properties[name];
  return false;
<!--EndFragment-->
Thanks,
Dave
Mar 30, 2009 at 3:54 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Mar 30, 2009 at 4:05 PM
I think the new default case you suggest makes sense for all languages, not just C++. The same set of macros are valid across all the languages I deal with. Plus you can eliminate a few cases in your current switch statement because they all need to be handled the same way (SolutionPath, FrameworkVersion, FrameworkSDKDir) as the default case. Only put in a case statement for those macros that must be handled uniquely.
Mar 30, 2009 at 6:05 PM
Hi Cody,

Thanks for the feedback.

Note that macros are specific to C++.  The macro evaluation code is not required for the other language project types; e.g., C#, VB.NET and J#.  These project types can have references to MSBuild properties such as ProjectDir in the output path setting and other settings because the specified values are actually stored directly in an MSBuild project file - DocProject does not have to intervene at all.

It does make sense to have the default case pass-through MSBuild property values in C++ so that it feels more like other language project types.  And I agree that if I implement it this way then I could get rid of the cases that you mentioned, which are simply pass-through already.

- Dave