Archive for the ‘Visual Studio’ Category

Executing PowerShell in a Post-Build Event

This is another one of those tasks where I thought it should be simple. That should be a red flag right there. I ended up spending way too much time on this, and as it turns out it is really only a matter of syntax. I ran across a lot of incorrect information out there, so I figured I should post this and help make the links to the right content easier to find.

I was actually building my own cmdLet for PowerShell in C#, and decided I should deploy it using PowerShell, which seemed appropriate. For me, the basic stumbling block for getting this working was quotes. I had multiple paths in my script, all of which had spaces in them, which necessitated the use of nested quotes. This was quite hard to figure out, but Philippe had the right information. He also pointed to this article, which had a thorough explanation of how to call PowerShell from the command line, which is essentially what you are doing inside a post-build event.

Since my cmdLet was really for SharePoint, I later figured out how to add it using the SharePoint 2010 project type in Visual Studio and some declarative XML, making all the previous pain a moot point.

Discovering the PublicKeyToken of Your Assembly

For many reasons, I often need the PublicKeyToken of a signed assembly, such as creating custom controls or working with a product like SharePoint. Typically this information ends up in a .config file, but in my case I’m exploring Custom Data Generators for Visual Studio 2010 and need this info for an XML file Visual Studio uses. In the past, I’ve always used Reflector to figure out the PublicKeyToken. But in reading the MSDN docs about Custom Data Generators, I stumbled upon a way to do it right in Visual Studio from the Command Window.

Open a Command Window (View menu –> Other Windows –> Command Window). At the prompt type something like this:

? System.Reflection.Assembly.LoadFrom(@”<path>”).FullName

where the path is obviously the path to your own DLL (like C:\Users\dtruxall\Documents\Visual Studio 2010\Projects\DemoGenerator\DemoGenerator\bin\Debug\DemoGenerator.dll). If you get the path correct, the Command Window gives output like this:

“DemoGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=22402068dd2dab84”

That’s exactly what I need for my XML.

Posted on:
Posted in Visual Studio | Comments Off on Discovering the PublicKeyToken of Your Assembly

Connecting to TFS 2010 with Visual Studio 2008

I got error TF31002 when trying to connect to TFS 2010 with Visual Studio 2008:

TF31002 The Team Foundation Server name, port number or protocol is incorrect The Team Foundation server is offline Password is expired or incorrect.

The basic problem is that in Team Explorer, before Visual Studio Service Pack 1, you can’t enter a valid URL in the Add Team Foundation Server dialog, only a server name or IP address. Unfortunately TFS 2010 changed the URL of the server to this format: http://<servername>:<port>/tfs/, adding a virtual directory that TFS 2008 does not have. Pre sp1 this syntax is not allowed in the dialog box. Just putting in the server name produces the above error, which, in the irritating way that error messages work, is completely correct since the services can’t be found because they now reside in a virtual directory.

To get Visual Studio 2008 to connect to Team Foundation Server 2010, there are definitely some steps you need to follow. I found a bunch of mostly correct information, but nothing exactly right (beta and RC were widely available) so I figured I’d post it here.

To begin with, you need to install the following, in this order to Visual Studio 2008:

  1. Team Explorer for TFS
  2. Visual Studio 2008 sp1
  3. Visual Studio Team System 2008 Service Pack 1 Forward Compatibility Update for Team Foundation Server 2010

If you already installed Service Pack 1 and need install Team Explorer, you will need to re-apply the service pack.

Enter the URL like this:

http://<servername>:<port>/tfs/

Add a TFS Server

Now you should be good to connect to the server.

Setting up MSDeploy on a Development Server

It’s not enough to just install MSDeploy on a server to allow Visual Studio 2010 to connect to the server. If you don’t follow the steps below, you will probably get 403 errors when trying to connect.

  1. When adding the Web Server (IIS) role, be sure to install Management Service.
  2. In the Services snap-in, find the Web Management Service and set its startup to Automatic (it’s manual by default). Don’t start it yet.
  3. Open the Internet Information Services Manager, and select the server.
  4. Open the Management Service feature.
  5. Check Enable Remote Connections.
  6. Choose a port (or keep the default), IP, Certificate, choose any restrictions you might require.
  7. In the Actions part of the right pane, click Apply.
  8. Click the Start link in the right pane.

Now IIS is configured to accept incoming connections. Open a port on the firewall for the port (8172 by default) you selected in step 6 above.

Install MSDeploy. Make sure you start the Web Deployment Service after the install, and set the service startup to Automatic.

Now you can use the Publish feature of Visual Studio 2010 to push directly to your development server.

See also: http://msdn.microsoft.com/en-us/library/dd465337.aspx

Posted on:
Posted in IIS, MSDeploy, Tools, Visual Studio | Comments Off on Setting up MSDeploy on a Development Server

Ann Arbor Day of .Net 2010

I’ll be speaking at the Ann Arbor Day of .Net on Saturday, May 1st, 2010. It’s being held at Washtenaw Community College. Register for the event at http://www.dayofdotnet.org/AnnArbor/Spring2010/Registration.aspx 

Here’s the abstract for my talk:

The Demise of Xcopy Deployment

One of the great features of .Net when it first released was Xcopy deployment. No more .dll registrations, just copy the files to the web server. While this was a great feature for Microsoft developers, new problems emerged, specifically around managing web.config. Sections like connection strings and custom errors need to be managed between environments, which meant many copies of the files or scripts to change them. Other necessary steps, like managing permissions and IIS configuration were still outside the Xcopy process. A recent tool, MSDeploy, is now integrated into Visual Studio 2010 and makes managing these issues easier. Besides web.config, MSDeploy also manages file deployments and synchronization, ACLs, and IIS settings. If your deployments have multiple steps, need ReadMe files, or can’t be done by someone outside your team, you need to learn MSDeploy!

Interview on Debugging

David Giard posted his interview with me for his show, Technology and Friends, talking about debugging and WinDBG.

More Debugging Links

As a follow up to my last post, I found more debugging links:

Posted on:
Posted in Tools, Visual Studio | Comments Off on More Debugging Links

Creating an Extraction Rule for VSTS 2008 Web Tests

Extraction rules are essentially for finding data in the HTTP response and placing it in the output context of the web test. There are a few built-in tests, but they mostly focus on the HTML tags themselves and the attributes. In my case I really needed the data between span tags. I think this could probably be done with the existing rules and some regular expressions, but I couldn’t resist the chance to write some code and learn something new.

All you need to do is place the class file in the Test Project and compile it. The rule automatically becomes available to the tests in the project.  Here is my class that finds a span for a given ClientId. It overrides the Execute method of the ExtractionRule base class and attempts to find a span for the given ID. If the span is found, it parses the HTML string to find the content of the span tag.

namespace WebTestDemo

{

    [System.ComponentModel.DisplayName(“Span Extractor”)]

    public class ExtractSpan : ExtractionRule

    {

        // The name of the desired input field

        private string nameValue;

        public string ClientId

        {

            get { return nameValue; }

            set { nameValue = value; }

        }

 

        public override void Extract(object sender, ExtractionEventArgs e)

        {

            string[] tagTypeFilter = new string[] { “span” };

 

            //Fail the test if nothing is found (this may need to be modified)

            e.Success = false;

 

            if (e.Response.HtmlDocument != null && e.Response.IsHtml)

            {

                try

                {

                    //Find the span tag based on ID. Exception if none found

                    HtmlTag result = e.Response.HtmlDocument.GetFilteredHtmlTags(tagTypeFilter).First(t => string.Equals(t.GetAttributeValueAsString(“ID”), this.nameValue, StringComparison.OrdinalIgnoreCase));

 

                    //The span was found (no exception), now find the data

 

                    //Get the location of the ID in the span tag

                    int startPosition = e.Response.BodyString.IndexOf(this.nameValue);

 

                    //Find the position of the data immediately following the closing angle bracket of the span,

                    //  accounting for the > character as well

                    startPosition = e.Response.BodyString.IndexOf(“>”, startPosition) + 1;

 

                    //Get the position of the closing tag for the span

                    int endPosition = e.Response.BodyString.IndexOf(“</span>”, startPosition);

 

                    //Fetch the content

                    string content = e.Response.BodyString.Substring(startPosition, endPosition – startPosition);

 

                    //Add the value to the context output. This could just as easily go to a file or a DB

                    // this step is not necessary for the extraction to succeed

                    e.WebTest.Context.Add(this.ContextParameterName, content);

 

                    //Mark the extraction as successful

                    e.Success = true;

                }

                catch (Exception)

                {

                    e.Success = false;

                    e.WebTest.Context.Add(this.ContextParameterName, string.Format(“span tag id={0} not found”, this.nameValue));

                }

            }

        }

    }

}

Now that I have the class, I need to wire it up to a URL in a web test. Right-click the URL and choose Add Extraction Rule…

AddRuleToTest[1]

I need to set two properties:

  1. Context Parameter Name. This comes from the base ExtractionRule class, and is the name for the data that ends up in the output.
  2. ClientId. This is a custom property from my class. It is the ClientId of the rendered control in the HTML output. The class finds the span with this name and returns the data.

Now when I run the test, if the ClientId I specified was found, it shows up in the Context output after running the test. The Context Parameter Name was “SpanData” in this case:

ExtractionRuleResults[1]

This could be made more robust by not coding specifically for spans. Certainly there could be issues if the tag ID is used more than once or if there is significant nesting of spans within the tag you are trying to find. This code is intended to prove out the concept, it could certainly be made stronger.

One thing I want to mention is that all the code samples I have run across (MSDN included) show the RuleName property as the way to display the extraction rule name in the Visual Studio UI. But under compilation this property comes up as obsolete. I found the answer on Ed Glas’s blog. The obsolete message mentioned using attributes, but this info was not discoverable, so I was quite grateful for that posting to get the syntax correct.

Helpful Links

Must Read VSTS – Testing Related Blogs and Introductory Articles

How to: Create a Custom Extraction Rule

Custom Extraction Rule and Generating a Code Test from VSTS

ASP.NET 2.0 and Global.asax: What not to do

I deployed a site today that has some code in the Global.asax event handlers. I let Visual Studio 2008 add the file to my project when I created it, and it put the code directly in the file inside <script runat=”server”> tags. I went with it. So when I deployed the file, none of the events fired. Ever. The lesson is: Don’t put your code in the global.asax file. Apparently this problem is by design. There is a vague KB Article on this problem, but the solutions aren’t all that helpful, I didn’t want to pre-compile, and the first solution made no sense at all. A little searching and I found one good solution: put a class that inherits HttpApplication in the App_Code folder as described here. What I don’t understand is why Visual Studio adds the file that way if it isn’t going to work on an xcopy deployment. Microsoft seems to go out of their way to protect us from ourselves so often that I am surprised the IDE does something intentionally that won’t work.

Posted on:
Posted in ASP.NET, Visual Studio | Comments Off on ASP.NET 2.0 and Global.asax: What not to do

Links for VSTS Database Professional Edition

Resources

Team Site
http://msdn2.microsoft.com/en-us/teamsystem/aa718764.aspx

Product Forum
http://forums.microsoft.com/msdn/showforum.aspx?forumid=725&siteid=1

Good Blogs
http://blogs.msdn.com/camerons
http://blogs.msdn.com/sachinre

 

Downloads

Service Release 1
http://support.microsoft.com/kb/936612/

PowerTools
http://go.microsoft.com/fwlink/?LinkId=88852

Posted on:
Posted in Visual Studio, VSTS | Comments Off on Links for VSTS Database Professional Edition