Different behavior between .sln and .sln.proj file

Hi
I just discovered an interresting issue.

I have created my own targets file that are called from my project file called Testproject.proj.
I have changed the import line in the proj to look like this
 <Import Project="$(SolutionDir)..\MyCustomTask.targets" />

The interresting thing is that when I run my Msbuild command on the solution(Testsolution.sln) that contain the proj file it does not resolve SolutionDir correctly. But when I run MSBuild on the generated  Testsolution.sln.proj SolutionDir does resolve correctly.

Here is the output with the command:
MSBuild Testsolution.sln
Microsoft (R) Build Engine Version 2.0.50727.26
[Microsoft .NET Framework, Version 2.0.50727.26]
Copyright (C) Microsoft Corporation 2005. All rights reserved.
C:\vs2005\Demo\TestProject.csproj(295,11): error MSB4019: The imported project "C:\TargetFiles\Ocean.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.
Build started 30.09.2005 17:01:27.

MSBuild Testsolution.sln.proj
Microsoft (R) Build Engine Version 2.0.50727.26
[Microsoft .NET Framework, Version 2.0.50727.26]
Copyright (C) Microsoft Corporation 2005. All rights reserved.
Build started 30.09.2005 17:06:19.



Answer this question

Different behavior between .sln and .sln.proj file

  • KoMas

    Hello Agile,

    Thank you for reporting the issue. This issue appears to be a bug in msbuild and we will file a bug for it.

    There are couple of workarounds that you can use.

    1) You can specify the SolutionDir as a property in command line
    msbuild /p:SolutionDir=c:\foobar

    2) You can set the SolutionDir as an environment variable

    If these are not applicable to your scenario please send us additional information and we will do our best to provide you with a temporary solution.

    Thank you,

    Regards,

    Jay Shrestha
    (jaysh@microsoft.com)
    < xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


  • Flame_Djinn

    Dan
       Could you please provide a snippet that shows how to set msbuildemitsolution Appreciate your help

  • delomar

    Dan

     I tried using 'subst' and that helped. Wonder why it works now. Its still the same mapping. I have no idea. I set up a batch file with

    "subst Q: E:\Projects\bin"

    and called it before the MSBuild task in Cruise Control.

    Thanks
    Kavitha

  • Nick Hertl

    I have made my own .targets file that adds some functionality to the build process. I want this file to be available both on the developers desktops and on the build server. The easiest and most 'correct' way of doing this is to check in the file into our sourcecontrol system. And letting developers sync to it as thay would sync to the rest of the code.
    This causes the problem that I don't know anything about the individual developers local area. The only constant I happen to know is the relative location between the solution files and my .targets file.
    The solution consist of multiple projects, but there is no certanty where that project is located.
    On the build server I will build several solutions, and even some "solution groups".
    So non of the provided workarounds is really working for me.

    Is any of the other solution variables available

    I thought that you just converted the sln file to a .targets file and then executed the file. This does not seem to be the case then. Which is a pity.

    On a side note and probably not directly related to msbuild; I loaded the solution in visual studio and everything run fine. But one part of my custom targets file is dependent on if you are running debug og release. And changing from debug to release inside of visual studio did not lead to a reload of the properties from the msbuild file. Does this mean that visual studio is not using msbuild for build anyway, but only reads the configuration files on startup. Or is it reading the files and temporary creating its own before executing the build


  • ovmidori

    Just set an environment variable. Eg., at a cmd.exe prompt:

    set msbuildemitsolution=1

    then you can build in that window and it will create the .sln.proj file.

  • Keith Murry

    (The problem is that in order to correctly build mixed-language solutions we have to probe imports of all projects in the solution before actually building the solution -- and at this point SolutionDir etc are not yet defined.)

    Another workaround to that might work for you depending on your scenario is using a relative path:

    <Import Project="..\..\foo.targets"/>

  • Manoj Kumbhar

    Hi Agile,

    1) We do convert the sln file into a synthetic project. (To see it, set the environment variable msbuildemitsolution=1 and build -- a .sln.proj file will appear, which is what we are normally building in-memory.) However, this problem is occurring during the scanning we do to create that in-memory project, before the project is built, which is why those properties are not yet defined.

    2) Note that although you see an error, we are actually continuing the build. The build should succeed: however your logger (for example the console logger we provide) will spot the error message and indicate the build failed. So another possible workaround might be to add a condition to your Import, to prevent the import if '$(SolutionDir)'=='' -- then it should be invisible during the scanning. I haven't tried this, though. This assumes your targets file does not contain project-to-project references, which is what the scanning is looking for.

    Yet another workaround might be if you can make the path relative to the root of your sync'ed tree (what we call an enlistment), or some other place in the tree that perhaps is set in your developers' environments.

    3) I suspect that VS does not re-evaluate the targets file when you switch configurations, only the main project - but I'll have to check this.

    Dan (msbuild@microsoft.com)

  • banjo picker

     DanMoseley wrote:


    1) We do convert the sln file into a synthetic project. (To see it, set the environment variable msbuildemitsolution=1 and build -- a .sln.proj file will appear, which is what we are normally building in-memory.) However, this problem is occurring during the scanning we do to create that in-memory project, before the project is built, which is why those properties are not yet defined.


    Can you not set the properties before starting the scanning The solutionname and path is getting picked up from the starting file location anyway.

     DanMoseley wrote:


    2) Note that although you see an error, we are actually continuing the build. The build should succeed: however your logger (for example the console logger we provide) will spot the error message and indicate the build failed. So another possible workaround might be to add a condition to your Import, to prevent the import if '$(SolutionDir)'=='' -- then it should be invisible during the scanning. I haven't tried this, though. This assumes your targets file does not contain project-to-project references, which is what the scanning is looking for.


    Well, in my case it just means that if the SolutionDir is '' I should never build at all. And not beeing able to build at all does not really help ;) But this can be a useful workaround in other situations.

    I am starting to wonder if I have somehow attacked the whole issue in an non-intended way.
    All I want do to is customize the build process. And I want my custom customization to be stored in source control and I don't want to mess with the official files becuase that would change the way the developers build other projects that does not need this special steps. And I don't want to reimplement my changes when later versions (with minor changes) of the standard targets files are released.


     DanMoseley wrote:

    3) I suspect that VS does not re-evaluate the targets file when you switch configurations, only the main project - but I'll have to check this.


    Is this a feature that is supposed to change or is it planned to be this way

    I have some related "bugs" as well.
    Will create a seperate thread for this.

  • sulu

    Kavitha,
    I tried referencing a managed assembly that was on a mapped drive, and build works fine for me within and outside VS.

    Can you please log an issue at http://lab.msdn.microsoft.com/productfeedback/ with full repro steps so we can look into your issue

    Thanks
    Dan

  • Patrick MCormick


    Thanks Dan. That works! Ran into another issue though. We have placed all the external assemblies on a share and mapped a drive to the share. MSBuild does not resolve those assemblies. This is what I am seeing in the build log:

    Considered "Q:\Microsoft.Practices.EnterpriseLibrary.Configuration.dll", but it didn't exist.

    If I build using the IDE this works fine..


  • Matthew C Hill

    Well, that's good if you're up and going. If you do find a bug, log it for us...

    Dan

  • Jason_Bullock

    Agile,
    We should be setting the property before the scanning. (It's a bug that we aren't.)

    I suggested the Condition=" '$(SolutionDir)'=='' " workaround because (1) on the scanning, it won't be set, and we'll ignore the import, which is probably benign, then (2) when we do the actual build, the property will be set, so we will do the import. Seems worth a try, anyway


  • Different behavior between .sln and .sln.proj file