Build OpenAccess Project Using MSBuild on a Machine Without OpenAccess Installed

OpenAccess ORM is a powerful ORM tool that integrates very well into Visual Studio. It uses wizards and is tightly integrated, which makes it easy to pick up and start using. However, this same asset also provides a challenge when using this tool along with MSBuild on a machine without OpenAccess installed. There are some adjustments that needs to be made, since it is designed to be used with Visual Studio, so we have to add a couple of extra bits to get MSBuild to be able to build a project correctly.

So if you’re using the OpenAccess ORM tool and you want to use a build server you’ll need to make a couple of configuration changes to allow you to achieve this. Since I use a continuous integration server on pretty much every project I work on, I ran into this issue. There are a few things you need to do to get this working.

The first step to getting this working is to get the required dlls copied to a local directory. This is important because the build server will need to have these references for the project. To get these files all you need to do is look to see where the reference is coming from in your projects. In my case the location is.

C:\Program Files (x86)\Telerik\OpenAccess ORM\bin

So I copied the files being referenced by my project from here and put them into a lib folder in a relative directory for my project. I then removed all of the references to the libraries in their install directories and added the references back in this time pointing to the local directory.

AddLocalReferences

Once you have everything local you’ll want to make sure you got all of the required libraries by building your solution. The build should succeed.

When working with OpenAccess, it is important to know that the assembly used for persistence is going to be Enhanced by OpenAccess ORM. After Visual Studio builds that project it kicks off VEnhance.exe to inject IL into the library with added functionality.

This is the step that we next need to add in to our build so that we can achieve the desired result.

Find the VEnhance.exe file on your development machine. It should be located in a directory similar to this one.

C:\Program Files (x86)\Telerik\OpenAccess ORM\sdk

Copy that directory somewhere local to your project. We will need it in a minute. You also need to copy your Telerik.OpenAccess.dll into the local directory you created with the VEnhance.exe file. The executable will need that dll to be there in order for it to do the enhancement.

We will need to create a targets file which we will import into our project file. You can copy the one I have listed here and customize it to your needs. It is basically just the instructions to tell your project how to call the VEnhance executable. You will need to change the relative directory to your OpenAccessToolsDirectory in this targets file to reflect where you put the VEnhance.exe file.

enahnce.targets

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <PropertyGroup>
   <OpenAccessToolsDirectory>$(SolutionDir)..\util\Telerik</OpenAccessToolsDirectory>
</PropertyGroup>
 
 <Target Name="EnhanceAssembly" Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)'">
   <Copy SourceFiles="$(TargetPath)" DestinationFiles ="$(TargetPath).notenhanced"/>
   <Copy SourceFiles="$(PdbFile)" DestinationFiles ="$(PdbFile).notenhanced"/>
   <Exec IgnoreExitCode="false"
         WorkingDirectory="$(TargetDir)"
         Command="&quot;$(OpenAccessToolsDirectory)\venhance.exe&quot; -verboseMode:1 -signAssembly &quot;-keyFile:$(ProjectDir)$(AssemblyOriginatorKeyFile)&quot; &quot;-assembly:$(TargetPath)&quot;"
         Condition="'$(AssemblyOriginatorKeyFile)'!=''" />
   <Exec IgnoreExitCode="false"
         WorkingDirectory="$(TargetDir)"
         Command="&quot;$(OpenAccessToolsDirectory)\venhance.exe&quot; -verboseMode:1 &quot;-assembly:$(TargetPath)&quot;"
         Condition="'$(AssemblyOriginatorKeyFile)'==''" />
   <Copy SourceFiles="$(TargetPath)" DestinationFolder ="$(IntermediateOutputPath)"/>
   <Copy SourceFiles="$(PdbFile)" DestinationFolder ="$(IntermediateOutputPath)"/>
 </Target>
 <Target Name="PeVerify" Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)'">
   <GetFrameworkSdkPath>
     <Output TaskParameter="Path" PropertyName="SdkPath" />
   </GetFrameworkSdkPath>
   <Exec WorkingDirectory="$(SdkPath)bin" Command="peverify.exe /nologo &quot;$(TargetPath)&quot;" />
 </Target>
 <PropertyGroup>
   <PdbFile>$(OutputPath)\$(AssemblyName).pdb</PdbFile>
   <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
   <PrepareForRunDependsOn>
     $(PrepareForRunDependsOn);
     EnhanceAssembly;
     PeVerify
   </PrepareForRunDependsOn>
 </PropertyGroup>
</Project>

This file needs to be imported at the end of your project file. So you’ll want to open your project file using a text editor not Visual Studio. Remember that project files are really just XML so we can go in and made changes to their source code. We need to do this if we want to get our targets file included.

At the bottom of the file you should see XML that looks roughly like this.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" 
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Pretend this is all of the rest of the project file -->
  <ProjectExtensions>
    <VisualStudio>
      <UserProperties OpenAccess_ConfigFile="App.config" 
          OpenAccess_ConnectionId="SilverlightAnalyticsExpressConnection" 
          OpenAccess_Enhancing="true" 
          OpenAccess_UpdateDatabase="false" 
          OpenAccess_EnhancementOutputLevel="1" 
          OpenAccess_UseMSBuild="True" />
    </VisualStudio>
  </ProjectExtensions>
</Project>

 

All we have to do is add in one line and change it to this using a relative path to where we placed the targets file. I admit I didn’t really know the best place to put it so I put it with the Telerik class libraries for my project.

<Import Project="..\..\lib\Telerik\enhance.targets" />
<ProjectExtensions>
  <VisualStudio>
    <UserProperties OpenAccess_ConfigFile="App.config" 
        OpenAccess_ConnectionId="SilverlightAnalyticsExpressConnection" 
        OpenAccess_Enhancing="true" 
        OpenAccess_UpdateDatabase="false" 
        OpenAccess_EnhancementOutputLevel="1" 
        OpenAccess_UseMSBuild="True" />
  </VisualStudio>
</ProjectExtensions>

And now we should be able to commit our changes and everything should work correctly on the build server. Cross your fingers. Make sure that all of your relative paths are correct. If you have any questions just post a comment below, on the Telerik forums, or both.

Comments