Showing posts with label VSTS. Show all posts
Showing posts with label VSTS. Show all posts

Monday, April 13, 2009

Team Foundation Server (TFS) Customizations in x64 Environments

While testing one of the Visual Studio Team System (VSTS) extensions I wrote I came across a scenario where the assembly was failing to load under the 64-bit version of Windows 7. It turns out that by default when one creates a project in Visual Studio 2008 the target is set to Any CPU. This in turn sets the Processor Architecture of the resulting assembly to MSIL, which essentially lets the Operating System (OS) decide which .NET Framework version and flavor to use (for all intense and purposes). This causes a problem when writing extensions for VSTS such as Work Item Tracking Custom Controls and other applications that leverage the Team Foundation Server SDK.

When loading such an assembly (of type MSIL, the default created when using the target Any CPU) in a x64 environment it will use the corresponding .NET Framework assemblies, which are in this case also 64-bit. The problem is that since all Team Foundation assemblies are 32-bit (or specifically of type x86) the mix causes the application to fail loading, in my case with the following error (as displayed in the Windows Event Log).

Faulting application ProcessTemplateItemDeployer.exe, version 1.0.0.0, time stamp 0x49de2a19, faulting module KERNEL32.dll, version 6.0.6001.18000, time stamp 0x4791ada5, exception code 0xe0434f4d, fault offset 0x000000000002649d, process id 0x%9, application start time 0x%10.

As you can see this is not very helpful. More details can be retrieved, however, from the error dialog itself that shows up when the application falters. In my case, the following snippet is displayed (extras removed for brevity).

See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.InvalidProgramException: Common Language Runtime detected an invalid program.
at InCycle.Tools.Forms.ImportProcessTemplateItem.ImportProcessTemplateItem_Load(Object sender, EventArgs e)
… (extra text removed …)
************** Loaded Assemblies **************
mscorlib Assembly Version: 2.0.0.0 Win32 Version: 2.0.50727.3521 (NetFXspW7.050727-3500)
CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll

What is interesting here is the last line. Notice that the mscorlib.dll that my application is referencing comes from the Framework64 folder of the .NET 2.0 Framework.

The solution I found, after quite a bit of research and trial and error, is to force the extensions to specifically target x86. Doing so forces the OS to load the 32-bit framework assemblies at run time, even in a 64-bit OS.

Refer to the article How to: Optimize an Application for a Specific CPU Type on MSDN for specific details on how to change the Processor Architecture.

Read full post...

Thursday, May 31, 2007

Automatically launch a silent remote MSI installation from Team Build

If you need to maintain an up-to-date test machine with the latest installation of the product you are testing, this post shows you how you can trigger the automatic installation of the latest components as a result of a successful build.

The logic has been tested using Team Build. However, since the underlying technology is MSBuild, the information described here does not require Team Build.

Prerequisites

MSBuild, and therefore Team Build, is unable to natively build Setup projects. In order to build a Setup project from within a Build Type you need to use the Visual Studio environment via the command line. This implies you will need to have access to Visual Studio. Preferably, the Visual Studio environment should be installed on the Build Machine.

In addition, because the Build Machine will be triggering the execution of the installation remotely, the user account under which the build process executes should have remote, administrative access to the Test Machine on which the installation will occur. Alternatively, you may use another user credentials to execute the installation but this means that these credentials will need to be part of the command that will launch the remote process, and therefore part of the Build Type project file.

Required Tools

Devenv - Executable used to launch Visual Studio. It can be used to build Setup projects from the command line, amongst other things. For details on all command line switches for Devenv refer to the MSDN online documentation. For details on building Setup projects using Team Build, please refer to the article Walkthrough: Configuring Team Foundation Build to Build a Visual Studio Setup Project.

PsExec - Allows execution of processes on other systems. PsExec is part of the Windows Sysinternals download and it is hosted at Microsoft TechNet.

Msiexec - The resulting MSI from a Setup project is not an executable. In order to perform actions outside of its default association, you require the use of a tool called Msiexec. This tool provides the means to install, modify, and perform operations on Windows Installer from the command line. Silent execution of these Windows Installer files can be accomplished through Msiexec.

Combining the Tools

In order to build a Setup project you need to use an Exec task in the AfterCompile target, as the following code snippet shows.

<Target Name="AfterCompile">
  ...
  <Exec Command="$(DevEnv) &quot;$(SolutionRoot)\Setup\Setup.vdproj&quot; /Build &quot;Release|Any CPU&quot;"/>
  ...
</Target>

Once you have access to the resulting MSI file, you can use the following command to execute a remote installation. Note that you will need to replace the information such as Server Name (MyServerName in the example below) and paths with yours.

<Target Name="AfterCompile">
  ...
  <Copy SourceFiles="$(SolutionRoot)\Setup\Release\Setup.msi" DestinationFolder="\\MyServerName\C$\Temp\Setup" />
  <Exec Command="$(PsExec) \\MyServerName -w &quot;C:\Temp\Setup&quot; msiexec /i &quot;C:\Temp\Setup\Setup.msi&quot; -quiet"/>
  ...
</Target>

Note: There have been cases where PsExec causes MSBuild to hang in the middle of a remote installation. I have yet to figure out why this may happen. If you run into this scenario and are able to fix it please share your experiences.

Alternate Scenario

There are times when you may want to trigger the installation on a remote machine from within your Visual Studio environment. For example, I do this often when I perform integration testing of MSBuild custom tasks, where I need to install the custom task in the Build Machine. Rather than doing it manually, I make it part of the Setup project's Post-build event.

I use the following script to automate the installation of my setups. In order for you to use the script, add it to your own Setup project's Post-build event and replace all the lines in bold with your own information.

echo ======================================================================
echo POSTBUILDSTEP for setup project.
 
set ServerName=YOUR_SERVER_NAME
set ServerPath=\\%ServerName%
set RemoteDrive=C
set MsiPath=Temp\YourProjectName
set MsiName=YourProjectNameSetup.msi
set RemoteMsiFilePath=%RemoteDrive%:\%MsiPath%
set RemoteMsiFileName=%RemoteMsiFilePath%\%MsiName%
set UncMsiFilePath=%ServerPath%\%RemoteDrive%$\%MsiPath%
 
echo Verifying/Creating temporary folder at "%UncMsiFilePath%"
if not exist "%UncMsiFilePath%" mkdir "%UncMsiFilePath%"
if errorlevel 1 goto BuildEventFailed
 
echo Uninstalling "%RemoteMsiFileName%" from server %ServerName%
psexec %ServerPath% -w "%RemoteMsiFilePath%" msiexec /uninstall "%RemoteMsiFileName%" -quiet
if errorlevel 1619 goto BuildEventContinue
if errorlevel 1606 goto BuildEventFailed
if errorlevel 1605 goto BuildEventContinue
if errorlevel 1 goto BuildEventFailed
 
:BuildEventContinue
echo Copying "$(BuiltOuputPath)" to "%UncMsiFilePath%"
xcopy /Y /R "$(BuiltOuputPath)" "%UncMsiFilePath%"
if errorlevel 1 goto BuildEventFailed
 
echo Installing "%RemoteMsiFileName%" on server %ServerName%
psexec "%ServerPath%" -w "%RemoteMsiFilePath%" msiexec /i "%RemoteMsiFileName%" -quiet
if errorlevel 1 goto BuildEventFailed
goto BuildEventOK
 
:BuildEventFailed
echo POSTBUILDSTEP for setup project FAILED
exit 1
 
:BuildEventOK
echo POSTBUILDSTEP for setup project COMPLETED OK
echo ======================================================================
echo.

With the script in place, whenever I build the Setup project the script will uninstall any previous version and re-install the new version of my custom task. This technique can be applied to pretty much any type of Setup project.

Read full post...

Wednesday, May 30, 2007

VSTS Database Professional using Remote SQL Server

My local SQL Server 2005 installation was damaged and I needed to be able to continue work on a project that makes use of the Visual Studio 2005 Team Edition for Database Professionals (VSTS DB Pro). The problem is that VSTS DB Pro requires a local SQL Server 2005 Developer Edition instance and above for it to work. So how does one make use of a remote SQL Server instance?

Perhaps there's another way to make it work with a remote SQL Server instance, but it appears that the current version of VSTS DB Pro does not natively support such configuration.

Luckily I found a MSDN Forum Post where Thomas Waldron suggests the use of a tool called TcpTrace to redirect the local 1433 port to that of a remote SQL Server instance. It works like a charm! I can now load my database projects.

Read full post...

Monday, February 19, 2007

Creating a customized Manual Test template for Visual Studio 2005

Update (01/12/2008): The post has been updated to show the differences with respect to Visual Studio 2008. The corresponding notes have been written in blue.

Part of the work we do at InCycle Software is help our customers install and configure Visual Studio Team System (VSTS). This includes the customization of work items, reports, process guidance, etc. For some customers, we even help them customize some of the templates.

Visual Studio 2005 Team Suite and Visual Studio 2005 Team Edition for Software Testers have templates specific to testing. One of these test templates is the Manual Test. There are two Manual Test formats: Text and Word. The steps to follow will show you one way to customize the look and structure of the Word format document and package it to create your own template.

I will assume that you are somewhat familiar with the Visual Studio environment and that you already know how to create Solutions and Projects. For these and other walkthroughs please refer to the Samples and Walkthroughs pages in MSDN.

The testing templates in Visual Studio 2005 are nothing more than extensions to the environment. In order to create a complete extension you would need to use the Visual Studio SDK. Creating a full Visual Studio extension is beyond the scope of this post.

With the help from Sarah Cameron, one of my colleagues at work, we have polished and divided the process into three main steps.

Create the Template

1. Start with the existing Manual Test template that can be found in your Visual Studio's Item Template folder. In my installation the path is D:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ItemTemplates\CSharp\1033. The template file name is ManualTestWordFormat.zip.

Note: In Visual Studio 2008 the above path would be D:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates\CSharp\1033. The template file name is the same. The path varies from Microsoft Visual Studio 8 to Microsoft Visual Studio 9.0.

2. Create a folder that will contain your customized template files. In this example, I will call the folder InCycleManualTest. This will serve as a staging area and is really optional.

3. Extract the contents of the ManualTestWordFormat.zip into the InCycleManualTest folder. The folder should now contain two files: ManualTest.mht and ManualTest.vstemplate.

4. Rename both extracted files to match the name of your template folder. In this example, the files are renamed to InCycleManualTest.mht and InCycleManualTest.vstemplate, respectively.

5. Open the .mht file in Microsoft Word and modify the document to suit your needs. When you are done you can save the document and close Word. You now have the document template contents for your customized Manual Test.

6. Open the file .vstemplate in a text editor such as Notepad. You should see the contents as an XML-formatted document. The document looks like the following.

<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
<TemplateData>
<Name Package="{52CBD135-1F97-2580-011F-C7CD052E44DE}" ID="113"/>
<Description Package="{52CBD135-1F97-2580-011F-C7CD052E44DE}" ID="109"/>
<Icon Package="{52CBD135-1F97-2580-011F-C7CD052E44DE}" ID="107"/>
<ProjectType>CSharp</ProjectType>
<SortOrder>10</SortOrder>
<DefaultName>ManualTest.mht</DefaultName>
<TemplateGroupID>TestProject-V1</TemplateGroupID>
<TemplateID>TestProject-V1-WordManualTest</TemplateID>
</TemplateData>
<TemplateContent>
<ProjectItem ReplaceParameters="false" OpenInEditor="true">ManualTest.mht</ProjectItem>
</TemplateContent>
<TestProjectData>
<LongDescription Package="{52CBD135-1F97-2580-011F-C7CD052E44DE}" ID="112"/>
<Helpkeyword Package="{52CBD135-1F97-2580-011F-C7CD052E44DE}" ID="105"/>
</TestProjectData>
<WizardExtension>
<Assembly>Microsoft.VisualStudio.QualityTools.Wizard.TestProjectWizards</Assembly>
<FullClassName>Microsoft.VisualStudio.TestTools.TestProjectWizards.TestItemWizardExtension</FullClassName>
</WizardExtension>
</VSTemplate>

Note: In Visual Studio 2008, the Version of the VSTemplate is 3.0.0. If you start with the template from the correct folder you will already have this version set correctly.

At this point the document represents the Manual Test Word format item template. We need to make some changes to add our customized template specific information.

Specifically update the following tags: Name, Description, DefaultName, TemplateID, and ProjectItem. Remove or replace the contents of the TestProjectData tag.

Save the document.

Note: It is very important that the TemplateID is unique. If it matches an existing template it will override its associated document.

Note: If you want to use special characters in the Name or Description of the template you will need to use the equivalent escape character (same XML rules apply to the .vstemplate document). For example, if you want to include a word that contains the French character "é" (no quotes) then you will need to replace it with its equivalent escape character "&#233;" (no quotes). Failing to do so will cause the template to fail registration without any error message.

The following is the resulting InCycleManualTest.vstemplate file used in this example.

<VSTemplate Version="2.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name>InCycle Manual Test (Word format)</Name>
<Description>Customized manual template</Description>
<Icon Package="{52CBD135-1F97-2580-011F-C7CD052E44DE}" ID="107"/>
<ProjectType>CSharp</ProjectType>
<SortOrder>80</SortOrder>
<DefaultName>InCycleManualTest.mht</DefaultName>
<TemplateGroupID>TestProject-V1</TemplateGroupID>
<TemplateID>InCycleManualTest</TemplateID>
<ShowByDefault>false</ShowByDefault>
</TemplateData>
<TemplateContent>
<ProjectItem ReplaceParameters="true" OpenInEditor="false">InCycleManualTest.mht</ProjectItem>
</TemplateContent>
<WizardExtension>
<Assembly>Microsoft.VisualStudio.QualityTools.Wizard.TestProjectWizards</Assembly>
<FullClassName>Microsoft.VisualStudio.TestTools.TestProjectWizards.TestItemWizardExtension</FullClassName>
</WizardExtension>
</VSTemplate>

7. Repackage the files you previously extracted and modified into a zip file and call it the same name as the folder you created. In this example, the compressed file is called IncycleManualTest.zip. Verify that the zip file does contain your two files and that these files do have your changes.

Note: It is very important that the files reside in the root of the zip file. If not, the template will not register correctly.

Deploy the Template

8. Copy the modified exported template zip file to your Visual Studio's Item Template folder. In this example, I copy the file IncycleManualTest.zip to my folder D:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ItemTemplates\CSharp\1033.

9. If updating an existing template you must first remove any previous template from Visual Studio’s Item Template Cache, which gets copied during the initial installation.

For example, if updating the IncycleManualTest.zip template I would remove the corresponding IncycleManualTest.zip file from my folder D:\Program Files\Microsoft Visual Studio 8\Common7\IDE\ItemTemplatesCache\CSharp\1033 before installing the new template. This is to ensure the new template is correctly updated in the cache.

10. Install your customized template. For the template installation command to work correctly you need to run the Visual Studio 2005 Command Prompt, as it initializes some environment variables required for the execution of the command.

The Visual Studio 2005 Command Prompt can be found under your Start menu. Look for the program group Microsoft Visual Studio 2005 / Visual Studio Tools. Launch it.

At this point, make sure you close any running instances of Visual Studio. At the command prompt type and execute the command devenv /InstallVSTemplates.

Visual Studio 2005 Command Prompt (click for full size)

Give it some time to complete. Note that even after the command prompt returns your hard disk may continue spinning. So, give it some more time to make sure the registration is finalized.

Test the Template

11. Test your new template. Launch Visual Studio and open/create a Test Project. Select New Test... like you did before to display the Add New Test dialog. You should now see your new Manual Test template.

Add New Test dialog with Custom template (click for full size)

In order to do a complete test of this template you should create multiple Manual Test using it and go through the paces to make sure the template is recognized in the Test View.

Read full post...