zoukankan      html  css  js  c++  java
  • Conditional project or library reference in Visual Studio

    Conditional project or library reference in Visual Studio

    In case you were wondering why you haven’t heard from me in a while, I’ve been busy, which isn’t really of much importance unless you know me on a personal level. What is relevant is that I recently graduated with a master in Game and Media Technology and am now in the process of making the project which I have been working on for my thesis open source. I’m very anxious to announce it, so you’ll read a lot more about it in the near future.

    The project uses two of my other open source libraries, located in separate repositories. Adding these projects to the solution and referencing them as project references has the advantage of easier debugging and facilitates making changes to them. However, I do not want to force anyone interested in making changes to the main project to having to download the other repositories as well. Therefore I opted to use DLL references. This has one major downside. Whenever I do make changes to one of the dependent libraries, I need to manually copy the newly compiled DLLs to the main project. Wouldn’t it be easy to use two separate solution files, one with project references, and one with DLL references?

    The first problem you’ll encounter is project references aren’t stored in the .sln file but in the .csproj file, which makes sense really. Since the .csproj file is shared by both solutions, we’ll have to conditionally reference either our DLLs or our projects, depending on which solution the project is opened in. This is possible usingMSBuild, but you will need to create a new project configuration. Setting the configuration of the project differently in one solution from the other allows you to differentiate between the two of them. The following is part of a .csproj file which conditionally loads a reference by checking whether the project configuration is set to ‘Debug With Project References’.

    <Choose>
      <When Condition="'$(Configuration)' == 'Debug With Project References'">
        <ItemGroup>
          <ProjectReference Include="..SomeProjectSomeProject.csproj">
            <Project>{6CA7AB2C-2D8D-422A-9FD4-2992BE62720A}</Project>
            <Name>SomeProject</Name>
          </ProjectReference>
        </ItemGroup>
      </When>
      <Otherwise>
        <ItemGroup>
          <Reference Include="SomeProject">
            <HintPath>..LibrariesSomeProject.dll</HintPath>
          </Reference>
        </ItemGroup>
      </Otherwise>
    </Choose>
     

    You could very well stop here, but I wanted to resolve another issue as well. Unless you follow a really strict folder structure, and force everyone else who wants to open your solution to do the same, the path used to reference the project can vary between people. Remember we are using separate repositories here, and the referenced projects aren’t included in the repository of the main solution, so relative paths don’t necessarily work. It is possible to specify the paths in an external ‘configuration’ file, and importing it into the .csprojfile. Additionally, as a fallback when the project can’t be found at the given path, it is also useful to load the DLL instead. This way you can choose to load one or more, but not necessarily all references as a project reference.

    The configuration file (ProjectReferences.txt):

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup Condition="$(Configuration) == 'Debug With Project References'">
        <SomeProject>..SomeProject</SomeProject>
      </PropertyGroup>
    </Project>

    Segment from the .csproj file:

    <Import Project="..ProjectReferences.txt" />
    <Choose>
      <When Condition="Exists($(SomeProject))">
        <ItemGroup>
          <ProjectReference Include="$(SomeProject)SomeProject.csproj">
            <Project>{6CA7AB2C-2D8D-422A-9FD4-2992BE62720A}</Project>
            <Name>SomeProject</Name>
          </ProjectReference>
        </ItemGroup>
      </When>
      <Otherwise>
        <ItemGroup>
          <Reference Include="SomeProject">
            <HintPath>..LibrariesSomeProject.dll</HintPath>
          </Reference>
        </ItemGroup>
      </Otherwise>
    </Choose>

    Notice the project configuration check now occurs in the configuration file. The ‘$(SomeProject)’ property is only set when using the ‘Debug With Project References’ configuration, thus in all other scenarios the DLL will be loaded instead since the ‘Exists()‘ check will fail.

    One last issue remains. We still need to manually copy the latest compiled DLLs to the ‘Libraries’ folder when changes were made for the solution which uses them to work as expected. We can exploit the fact that we now have the relevant project paths available in the configuration file. Using a post build event you can call a script which parses the XML data, and copies the DLLs to the correct location. This script should be called conditionally, only for the solution which includes the project references, and ideally also only for a Releasebuild. I used a small Ruby script which offers a lot more flexibility than a Batch script.

    The post build event:

    if "$(SolutionName)" == "SomeSolution With Project References" if "$(ConfigurationName)" == "Release" ruby $(SolutionDir)UpdateLibraryDlls.rb $(SolutionDir)
  • 相关阅读:
    java 将表情转换成字符串存入数据库
    java html websocket简单实现
    Java poi读取Excel表格中公式的计算值
    转盘代码,自己搞了一个
    html5 canvas画布
    cat命令查看文件指定行数
    CentOS7 安装 gpbackup 和 gpbackup-s3-plugin 来备份和还原 Greenplum 数据库
    QT5 打包发布Release应用程序
    CentOS7 安装Redis6.0.10
    ES系列(二):基于多播的集群发现实现原理解析
  • 原文地址:https://www.cnblogs.com/zhahost/p/4796343.html
Copyright © 2011-2022 走看看