Learn to use Visual Studio, Visual Studio Online, Application Insights and Team
Foundation Server to decrease rework, increase transparency into your application and increase the rate at which
you can ship high quality software throughout the application lifecycle
Note that this post was updated on June 5th to provide updates concerning the Visual Studio 2012 RC. The changes are highlighted.
In my last post, I’ve introduced the Code Index, explaining why use it, and how to get it. This post is about the first scenario that I mentioned: bulk indexing assemblies into the code Index. This topic requires that you have installed the VsVmSdk, as explained already.
In Visual Studio 11 Beta, the only way to bulk-index assemblies is by using MsBuild. The supported scenarios are:
- index assemblies as part of a build outside Visual Studio.
- index an arbitrary set of assemblies from the command line
You can use MSBuild directly from the command line to load artifacts into a specified code index. By default, the database will be created if it does not already exist.
As a minimum, you will need to specify the artifacts to be loaded. Optionally, the following parameters can also be specified: database name, SQL server name, connection string, and whether the database should be created if it does not exist. If the connection string is specified then the database name and SQL Server name parameters will be ignored.
The following examples show how you can use MsBuild to index assemblies. For simplicity, here we suppose that we are running in a console window, and that the current path is the the folder where the MsBuild tasks are installed (See § 2.3). If this is not the case, of course, you need to provide the full path for Microsoft.Repository.targets. Also note that the commands should really be on one line (but the blog page is too narrow for me to write everything on line, so I cut the command into 2 lines)
msbuild Microsoft.Repository.targets /t:LoadFiles /p:LoadFileSpec=*.dll
Effect: loads all matching files from the current directory into the default code index. A new database will be created if necessary
msbuild Microsoft.Repository.targets /t:LoadFiles /p:LoadFileSpec=*.dll /p:CreateRepository=false
Effect: loads all matching files from the current directory into the default code index. The database will not be created if it does not already exist
msbuild Microsoft.Repository.targets /t:LoadFiles /p:LoadFileSpec="**\*.dll;**\*.exe"
Effect: loads all matching files from the current directory and sub-directories into the default Repository (note the MsBuild syntax ** means “recursively”)
msbuild Microsoft.Repository.targets /t:LoadAFiles /p:LoadFileSpec=*.dll /p:RepositoryDb=MyCodeIndex
Effect: loads all matching files from the current directory into the specified database using the default SQL server
msbuild Microsoft.Repository.targets /t:LoadFiles /p:LoadFileSpec=*.dll /p:RepositoryServer=MyDivisionSqlServer
Effect: loads all matching files from the current directory into the default database on the specified SQL server
msbuild Microsoft.Repository.targets /t:LoadFiles /p:LoadFileSpec=*.dll /p:RepositoryServer=MyDivisionSqlServer /p:RepositoryDb=MyCodeIndex
Effect: loads all matching files from the current directory into the specified database on the specified SQL server
The command can be summarized as the following (between squared brackets I’ve represented optional commands)
Msbuild %ProgramFiles(x86)%\MSBuild\Microsoft\VisualStudio\v11.0\Repository\Microsoft.Repository.targets [ /t:LoadFiles ] /p:LoadFileSpec=Folder\*.dll | Folder\**\*.dll [ /p:CreateRepository=false ] [ /p:RepositoryServer=SqlServerInstanceName ] [ /p:RepositoryDb=DatabaseName ]
Another way of indexing assemblies is by creating an MSBuild project that sets the configuration properties (e.g. files to index, connection string etc …) then invokes the new Repository tasks and targets directly. You will then be able to index the assemblies simply by building the project from the command line e.g. msbuild SampleProject.proj
The following example (SampleProject.proj) shows a custom project that will load all of the .exe and the .dll files which name starts with “Build” located in the same directory as the target file into a database folder named “TargetFolder” of a database called “MyTestDb”. This database will be created under S:\SqlData.
<?xml version="1.0" encoding="utf-8" ?> <Project DefaultTargets="LoadArtifacts" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Custom project file to load all of the assemblies and executables in the same folder as the project file. Note that the "DefaultTargets" property has been set above to "LoadArtifacts". -->
<!-- Change the directory in which the database will be created. –> <RepositoryDirectory>S:\SqlData</RepositoryDirectory>
<!-- Change the database into which the data will be loaded. –> <Repository>MyTestDb</Repository>
<!—- Repository Folder into which the data will be loaded—> <TargetFolder>LastVersion</TargetFolder>
<!-- Specify the artifacts to load –> <ArtifactsToLoad Include="Build*.dll" /> <ArtifactsToLoad Include="*.exe" />
<!-- Import the core Repository tasks and targets-->
Note that, in the code index SDK Beta, the element describing the database used to be <RepositoryDb>MyTestDb</RepositoryDb>. From Visual Studio 2012 RC, it is now <Repository>MyTestDb</Repository>
I’ll recap here what you can use in your msbuild projects:
The following properties and item groups can be used to configure the loading process.
Used to be $(RepositoryDb) in Beta
Name of the database into which data should be loaded.
Ignored if $(RepositoryConnectionString) is specified.
Default value: Microsoft.VsCodeIndex
Default value used to be Repository in Beta
Name of the SQL Server.
Default value: (localdb)\v11.0
Full connection string to database to use.
Default value: calculated using $(RepositoryDb) and $(RepositoryServer).
Flag that indicates whether the specified Repository database will be created if it does not already exist.
Default value: True
Operating system directory in which the new database will be created (in order to control where to locate the database files)
Ignored if a new database is not created.
Default value: null
The list of artifacts to load (See the MsBuild targets below)
The target code index folder into which the artifacts should be loaded. In the code index, the information about indexed assemblies is stored in folders, which are the unit of deletion. Several assemblies can be stored in the same folder. If this parameter is not provided, then the name of the folder is computed (from the assembly name and a GUID)
File specification of files to load.
Examples of usage from the command line:
The following targets can be called
Low level task that provides maximum control of the execution of the loading process i.e. the user can specify all of the available configuration options.
Wrapper around LoadArtifacts to simplifying loading files from the command line. The user specifies the files to load using the $(LoadFileSpec) property.
The target uses this property to set @(ArtifactsToLoad) and then calls the LoadArtifacts target.
Updated on March 27th in 3.1.2, the target (/t:) was /t:LoadArtifacts whereas it should be and is /t:LoadFiles. Thanks to Lars for discovering the typo.