Showing posts with label VS 2008. Show all posts
Showing posts with label VS 2008. Show all posts

Friday, March 11, 2011

VS2010, TFS 2008 and Unit Tests

For the last couple of days I have been battling with TFS2008 and getting our build server to run the unit tests defined in a Visual Studio 2010 solution.

Previously we installed .Net 4.0 and updated the MsBuild path in the tfsbuild.proj file so our VS2010 solutions were building without a problem on the TFS2008 based build server. But the minute I tried to get the build server to run the unit tests in my solution, the build would partially fail and if looked in the BuildLog.txt file, this is the error I got:

Task "TestToolsTask"
MSBUILD : warning : Visual Studio Team System for Software Testers or Visual Studio Team System for Software Developers is required to run tests as part of a Team Build.  [Path\TFSBuild.proj]
  The previous error was converted to a warning because the task was called with ContinueOnError=true.
  Build continuing because "ContinueOnError" on the task "TestToolsTask" is set to "true".

Googling the error and you find out that you need Visual Studio 2010 Premium or Ultimate edition to be able to run unit tests as part of your build. So I went ahead and installed VS2010 ultimate and I still got the same damn error shown above.

It turns out that in addition to VS2010 (premium or ultimate) you also need VS2008 Development edition on the build machine. (In addition is the operative word here – you need both!). It turns out that the TestToolsTask is looking for VS2008 dev edition before running even a VS2010 based solution (and I am not sure if this for some required dlls or for licensing purposes – either ways – it sucks) (Obviously the reason I had to battle with this issue was that the build machine was never previously setup to run MsTests – even with Vs2008, else someone would have figured out that they needed VS2008 dev edition on that box).

Once I got VS2008 dev edition on that machine I was able to get the build a little further. HOORAY!

Some other things to note:

Once you get both VS2008 dev and VS2010 premium on that machine, you should delete the workspace used by the TFS service on the build machine (the easiest way to do this is to use the TFS SideKicks tool and search for all the workspaces on that machine and then delete the one that is being used for your build). This allows TFS to rebuild the workspace and all the files, but this time with MsBuild 4.0.

Now that I got one problem fixed, TFS decides to throw another one at me and the error that I get is as follows:

Task "TestToolsTask"
  Command:
  d:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe /nologo /searchpathroot:"path\Binaries" /resultsfileroot:"path\TestResults" /testcontainer:"path\Binaries\\\\Tests.dll" /publish:"TFSURL" /publishbuild:"vstfs:///Build/Build/26026" /teamproject:"Project" 
  The "TestToolsTask" task is using "MSTest.exe" from "d:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe".
  No platform specified for publish operation.
  For switch syntax, type "MSTest /help"
MSBUILD : warning MSB6006: "MSTest.exe" exited with code 1. [path\TFSBuild.proj]
  The previous error was converted to a warning because the task was called with ContinueOnError=true.
  Build continuing because "ContinueOnError" on the task "TestToolsTask" is set to "true".
Done executing task "TestToolsTask" -- FAILED.

[Update 3/14/2010]

The problem with MsTest is that it always use the generic error code of 1 when it fails. So it makes it extremely hard to figure out what is going on when it fails. I looked through a long list of online articles that had me doing a whole bunch of things and at the end the following is what fixed it for me:

  1. Need to Microsoft.TeamFoundation.Build.targets file to use the VS2010 dll instead of the VS2008 dll for the testToolsTask
    In the folder: “C:\Program Files\MSBuild\Microsoft\VisualStudio\TeamBuild\” on the build machine you will find the file “Microsoft.TeamFoundation.Build.targets”. Edit the following lines:
    Comment out the original line for the TesToolsTask:
  2. <UsingTask TaskName="TestToolsTask"
                 AssemblyFile="$(MSTestRefPath)\Microsoft.VisualStudio.QualityTools.MSBuildTasks.dll"
                 Condition=" '$(ProjectFileVersion)' == '2' "/>

    Insert the following line right after it

    <UsingTask TaskName="Microsoft.TeamFoundation.Build.Tasks.TestToolsTask"
                 AssemblyFile="c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
                 Condition=" '$(ProjectFileVersion)' == '2' "/>

    Make sure that the path to “Microsoft.TeamFoundation.Build.ProcessComponents.dll” is correct
  3. Next make sure that you have specified the platform in your TfsBuild.proj file:

    This is how it looks like in my TfsBuild.proj:

    <ItemGroup>
        <SolutionToBuild Include="$(SolutionRoot)/mySolution.sln" >
          <Targets></Targets>
          <Properties>Configuration=Release;Platform=Mixed Platforms</Properties>
        </SolutionToBuild>
      </ItemGroup>
      <ItemGroup>
            <ConfigurationToBuild Include="Release|Any CPU">
                <FlavorToBuild>Release</FlavorToBuild>
                <PlatformToBuild>Any CPU</PlatformToBuild>
            </ConfigurationToBuild>
      </ItemGroup>

    If the PlatformToBuild is not specified the “No platform specified for publish operation” error can occur.

With the above 2 fixes in place, the final thing that I needed to specify were which tests should be executed. This is done using one of the following 2 methods:

Specify the VSMDI file using the metadataFile node as follows:

<MetaDataFile Include="$(SolutionRoot)/mySolution.vsmdi">
            <TestList>TestListToExecute</TestList>
</MetaDataFile>

Or use the following node to define a wildcard to select the files that contain the tests:

<TestContainer Include="$(OutDir)\Tests.dll"/>

With that your TeamBuild should be executing all your unit tests.

Code-Coverage:

The only thing that I havent been able to get going is Code-Coverage on my solution. Here is what I have tried:

I have setup the VSMDI to use a testConfiguration for the unit tests. As part of the test-configuration, Code-Coverage is enabled and I have selected the dlls on which code-coverage should be run. With the above settings, some files (like data.coverage) get created in the drop folder, but TFS reports that code-coverage was not run.

After spending quite some time on this problem, I am just about ready to give up (especially because this post seems to state that code-coverage is not possible using TFS 2008 and VS2010 and .Net 4 built modules - http://social.msdn.microsoft.com/Forums/en-US/tfsbuild/thread/39aaaf43-0e3a-41c7-8b72-c1cabc9438e1/).

Tuesday, September 28, 2010

Visual Studio 2008–Change active item selection color

When an item is selected in the Solution Explorer of Visual Studio (2008), it shows up with a nice dark colored back ground which makes it easy to find the item.

image

But when the Solution Explorer does not have current focus, then the color used makes it extremely hard to determine which item currently has focus.

image

Here is what you need to do to change the back ground color of the selected item – when it is in a window that does not have current focus.

Open up the Window Color and Appearance dialog.

- On Windows 7, Go to “Appearance and Personalization” –> “Personalization” –> “Window Color and Appearance”

- Click on “Advanced appearance settings….”

Under “Item” select “3D Objects” and change the color for “Color 1”

image

(The original color was RGB = 240,240,240).

That should do it.

Note: This solution does not work for Visual Studio 2010.

Thursday, September 02, 2010

MSTests - Multiple tests with ID {GUID} found error

If you get the error “Multiple tests with ID {GUID} found.” when attempting to run a MsTest list, then it is one of the following:

If you are using VS2005 then – inheritance of tests is not supported.

If you are using VS2008 or newer, then just refresh your test-manager and the error should go away.

Wednesday, August 04, 2010

How-To: Turn off ReSharper hint to use “var” when possible

In my opinion it is the most annoying hint that ReSharper puts me through and the first thing I try to figure out how to turn off once I install it. (Especially when you start using ReSharper on an existing project – this error will start popping up all over the place).

To turn it off: Go to ReSharper ==> Options ==> Node “Inspection Severity” under Code Inspection and setup as shown below.

Resharper-TurnOffVar

Friday, June 04, 2010

VS 2010 and TFS 2008 and Office 2003

If you are stuck on TFS 2008 and Office 2003, then after you install VS 2010, you will find the office integration to TFS is broken. This is by design as the VS team decided to only support Office 2007 and up with VS 2010.

If you are truly stuck in Office 2003 then here is what you can do, to get back the integration:

1. If you already dont have VS2008 and Team Explorer 2008, then install just Team Explorer 2008.
http://www.microsoft.com/downloads/details.aspx?familyid=0ed12659-3d41-4420-bbb0-a46e51bfca86&displaylang=en

2. Install VS 2008 SP1.
http://www.microsoft.com/downloads/details.aspx?familyid=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en

3. Install the VS 2008 Forward Compatibility update.
http://www.microsoft.com/downloads/details.aspx?FamilyID=CF13EA45-D17B-4EDC-8E6C-6C5B208EC54D&displaylang=en

The office integration functionality is provided by a COM dll called “TFSOfficeAdd-in.dll”. To get back integration with Office 2003, you need to unregister the VS2010 version of this dll and then register the VS2008 version of this dll. (The dll is found in the “Common7\IDE\PrivateAssemblies” folder of the version specific Visual Studio installation folder).

Here are the commands:

Unregister VS2010 version of TFSOfficeAdd-in.dll
regsvr32 /u "c:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\TFSOfficeAdd-in.dll"

Register VS2008 version of TFSOfficeAdd-in.dll
regsvr32 "c:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PrivateAssemblies\TFSOfficeAdd-in.dll"

When you are ready to upgrade to Office 2007, just reverse the above 2 commands (i.e., run regsvr32 /u on the VS2008 dll and regsvr32 on the VS2010 dll).

Monday, April 26, 2010

TFS 2010 and Office 2003

In short: doesnt work! – TFS 2010 requires Office 2007 for managing your project.

Here is a hack that allows you to continue working with Office 2003 with TFS 2010. It is a hack because you cannot create a new file from VS 2010. The only way to create a new excel document linked to your project is from VS 2008. In addition there are some other issues, such as no support for tree of items, etc.

Here are the steps: http://blogs.msdn.com/team_foundation/archive/2010/04/24/vs-2010-and-tfs-with-office-2003.aspx

Tuesday, September 01, 2009

Developing for SilverLight 3

If you plan on using Visual Studio (2008) for SilverLight 3 development then remember to install the SilverLight 3 Tools for VS 2008.

Get if from:
http://www.microsoft.com/downloads/details.aspx?familyid=9442B0F2-7465-417A-88F3-5E7B5409E9DD&displaylang=en

If you create a project in Expression Blend 3 and you are unable to open the project in Visual Studio, then you most probably havent installed the Silverlight 3 tools for VS 2008 package.

If you have SilverLight 3 tools installed for Visual Studio – you should see the following project templates in the new project dialog:

image

Monday, August 17, 2009

Scrum for TFS (Concango Template)

Do you get the “No data available yet.” message when you try and view your Sprint View reports?

Make sure that the Sprint Start Date and End Date are set.

image

Thursday, June 18, 2009

TSD03006: User: [username] has an unresolved reference to Login [loginname]

I was getting this error everytime I tired to build my VSTS Database project. The project had been created as a “database project” and not a “server project”.

image

Because logins are server level objects, they do not get imported as part of the schema into the database project and hence you see the error.

The method that I used (and liked) to solve the problem was to create a 2nd database project which I setup as a “server project”. This one imported login ids and whole lot of other stuff. I then deleted all the other parts that belonged to the project, leaving behind only the login objects.

image 

Finally, I referenced this database project in my main database project.

image

Voila! and it worked!

Why do I prefer this (over just having a single server project)? because when you create your deployment script – there are 2 scripts created one thats based on the server project and the other based on your database project. In my case, the server project contains all kinds of crap that I typically never need unless I am standing up a new server, so I can ignore it and work only with the main database project.

Tuesday, May 19, 2009

TFS - Unit Test Adapter threw exception: Could not load file or assembly or one of its dependencies

If you ever get the following error:

Unit Test Adapter threw exception: Could not load file or assembly “dll module name” or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)

The most probable reason that is causing the error is that your modules are setup to be signed, but because you have enabled code coverage analysis (which adds code to the modules), the signing has been invalidated.

Here is how to fix it (or this is what I did to fix it - YMMV):

Under the Test menu of Visual Studio, goto Edit Test Run Configurations | Local Test Run (“testrun name”)

image

You have 2 choices: Disable Code Coverage Analysis, or if you keep code coverage analysis enabled, then you need to provide the same key file used to sign your original assemblies as the re-signing key file.

image

Sunday, January 18, 2009

Static Variables and their implications in ASP.Net websites

Are you using static variables in your ASP.Net websites? Do you know the implications that they have on your website? (Especially the security implications?)

Well, first off go visit this ASP.Net site which will demonstrate the dangers of using static variables in your website: http://www.aggregatedintelligence.com/Samples/StaticsDemo/default.aspx

There are 2 sets of text boxes. The first one stores values using static variables, the second set stores variables using the Session object. Try and type in each box and update the values using the buttons. Now try closing your browser and then go back to the site. Also, try and access the site from a different browser. See anything interesting? The first set of boxes will either end up showing you values that you typed in during a different session (if you closed and reopened the browser) or values from a different computer (if you closed and the reopened the page from a different computer) or values from another user (if another user changed the values while you were looking at the page).

This is a BAD code smell and here is a little bit about why it might get used and why you should not use it and what are the alternatives.

Why do developers use static variables? Typically, it is used to persist values in class member variables across post-backs. Normally, if you create a member variable and store a value in it – you will find that the value gets erased after a post-back (such as that caused by a button click event)

Why should you not use static variables? Static variables are global variables for that page. This means that they will hold their value across post-backs (which is the behavior the developer wants), but the value in that variable is also available to all users accessing the website!!!! Think about this for a minute: if you use a static variable to store the current user's login-id, or security level, or a password, then that value becomes available to anybody else who accesses that page. If your code is badly written – it is conceivable that the other user can gain access to data that they should not have access to. There is another problem, that can lead to weird behavior in your website. Static variables are not thread-safe. Each user that accesses your website is running within a separate thread. If 2 people do some action that tries to update the variable at the exact same time – you can get weird issues – such as web-site locking up. Basically, it boils down to the fact that the life-time of a static variable is for the life of the application (actually it is more like for the life time of the process hosting the website, but that is a detail we can gloss over for this topic). And furthermore, the scope of the static variable is page/application wide and NOT session specific. And those 2 are extremely important details to remember when you use a static variable in your ASP.Net web application.

Static variables should smell bad to you ALWAYS! (in an ASP.Net application that is - but read caveat below)

What should you use instead of a static variable? There are 3 places available to you to store values that persist across page post-backs: Session – use this when you need access to the variables value across multiple pages ViewState – use this when you need access to the variable only within the current page. (Don't use ViewState to store objects that can potentially get very large, such as DataSets, as this information gets serialized and sent to the client browser during each round-trip. Cache – One more location that you can store user specific information.

Caveat: What if you want to store a value that should be accessible across the website? There are always cases where one would want to set a variable that is then accessible across the website and all users that use that site. (A good example for such a variable is one that flags if the website is available or not, depending on which – logins to the site are allowed or denied). (Update: 02-24-2009: I have removed the recommendation of using ONLY the application object, this is because the Application object was made to provide an easy route to migrate old ASP apps. Using static variables - sensibly - can lead to more performant code). One can use the Application object instead of static variables, which is similar to Session object, only it is available to the entire application. Only thing to remember is that one should use locks on the static variables in the Application container to make it thread-safe (otherwise you might see weird run-time behavior and hours spent trying to debug them). This is not an issue with non-static variables stored in the Application object. When the data that you are storing is not temporary and not user specific, then you can use a static variable to store that information. A lot of the data used by your web-site is already static - one such example is the ConfigurationManager and this makes sense: the Configuration properties for your web-site apply site wide and are not user specific. Static variables are more performant than the Application object and one should keep this in mind when they are trying to decide which route they wish to take. (Also, using a static variable will typically lead to more readable code when compared to using the Application object).

Here is a good article on how to use Application object: http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312607

The bottom line is that: never use a static variable to store user-specific data.

Monday, January 12, 2009

Crystal Reports for Visual Studio: 2 useful C# functions

When I first started working with Crystal Reports, what I found troubling was that when you connect to a database and select a table to use in your report (or for that matter any stored procedure), you provide Crystal Reports with the connection information which is then stored in some hidden place within the RPT files. The reason that this was troubling to me was that there did not seem to be any way to point to have different databases for development and production.

Sure, I tried the "SetDatabaseLogon" that is available on ReportDocument within the CrystalReportSource object - but that never seemed to work. After a lot of frustration, what I ended up doing was creating data-sets and then creating reports using the data-sets. Then during run-time, I had a method that would return the data-set from the appropriate database (dev or production), which was then set into the report using "SetDataSource" that is also available on on the ReportDocument object in the CrystalReportSource object.

By setting the DataSource for the CrystalReport, I was able to get a solution where depending on what mode I was running the application - I was able to get the data from the development, test or production databases.

This solution worked fine and dandy for a while, until I came across a complex report that had a sub-report embedded inside it. The sub-report had to be run once for every record in the main report. This is something that cannot be done using the DataSource method, because, even though I could give CR the main report's data-source, I would not be able to provide a data-source for each sub-report that needed to be run.

This time while looking for a solution, I found out 2 things:

1. The reason SetDatabaseLogon does not work is that it only allows you to change the user-id and password. The four parameter version will not change the database and server names: It will change the user-id and password for all those objects that share the database and server name passed in as part of the arguments. (This information is unfortunately buried in the remarks part of the documentation).
2. To change the database that is being used one needs to use the "ApplyLogOnInfo" on each table (CrystalDecisions.CrystalReports.Engine.Table) that is in the CrystalReport object.

So here is my first useful C# function for working with CrystalReports. It is used to change the database used by CrystalReports to get its data. (use it when you need to use separate development, test and production servers as your data-source for CrystalReports)

public static void SetCRLogOnInfo(ReportDocument mainInRD, string dataSource, string userId, string pwd)
    {
        //do the main reports database
        TableLogOnInfo logonInfo = null;
        foreach (CrystalDecisions.CrystalReports.Engine.Table table in mainInRD.Database.Tables)
        {
            logonInfo = table.LogOnInfo;
            logonInfo.ConnectionInfo.ServerName = dataSource;
            logonInfo.ConnectionInfo.DatabaseName = "";
            logonInfo.ConnectionInfo.UserID = userId;
            logonInfo.ConnectionInfo.Password = pwd;
            table.ApplyLogOnInfo(logonInfo);
        }
        try
        {
            //now update logon info for all sub-reports
            if (!mainInRD.IsSubreport && mainInRD.Subreports != null && mainInRD.Subreports.Count > 0)
            {
                foreach (ReportDocument rd in mainInRD.Subreports)
                {
                    SetCRLogOnInfo(rd, dataSource, userId, pwd);
                }
            }
        }
        catch
        {
        }
    }
The second method is used to export the CrystalReport as a PDF file. The reason it takes a HTTPResponse, is that this snippet is used in a ASP.Net application and it outputs the PDF to the browser.
public static void ExportToPDF(CrystalReportSource crs, HttpResponse response)
{
    try
    {
        response.Buffer = false;
        response.ClearContent();
        response.ClearHeaders();
        response.ContentType = "application/pdf";
        
        Stream pdfStreamFromCR = crs.ReportDocument.ExportToStream(ExportFormatType.PortableDocFormat);
        byte[] outputBuffer = new byte[(int)pdfStreamFromCR.Length];
        pdfStreamFromCR.Read(outputBuffer, 0, (int)pdfStreamFromCR.Length);
        response.BinaryWrite(outputBuffer);
        response.Flush();
        response.End();
    }
    catch(ThreadAbortException)
    {
        //expected do nothing
    }
    catch (Exception ex)
    {
        //Log4Net
    }
}

(updated on 1/12/2008)

Monday, January 05, 2009

Microsoft Visual Studio 2008 License Terms

license I was trying to determine if the VS2008 license terms allowed a single developer to install the IDE on multiple machines (basically at work and at home or my laptop). I have known for a long time that the Visual Studio license has been developer based, but I needed to find the exact wording in their EULA.

Weirdly, the EULA is not easy to find on the Internet. So after a lot of searching, I found some of the EULAs and here is the list for the benefit for others.

As for the part that allows us to install VS on multiple machines owned/used by the developer, here is what I think is the relevant wording from the license document (taken from Microsoft Software License Terms: Microsoft Visual Studio 2008 Professional Edition and Trial Edition)

1. OVERVIEW.
a. Software.
The software includes development tools, software programs and documentation.
b. License Model. The software is licensed on a per user basis.

2. INSTALLATION AND USE RIGHTS.
a. General.
One user may install and use copies of the software to design, develop, test and demonstrate your programs. Testing does not include staging on a server in a production environment, such as loading content prior to production use.
b. Included Microsoft Programs. These license terms apply to all Microsoft programs included with the software. If the license terms with any of those programs give you other rights that do not expressly conflict with these license terms, you also have those rights.

Based on the above license terms, one user can install Visual Studio on multiple machines as long as each installation is for that specific user's use.

And here is a list of links to the actual license terms documents

Visual Studio 2008 Standard
Visual Studio 2008 Professional
Microsoft Visual Studio Team System 2008 Team Foundation Server, Standard Edition, Workgroup Edition

Here is the final Google Search that got me the documents.

Note: The grant of license to install multiple copies per developer seemed to be a lot more defined in the VS 2003 EULA:

If you are an entity, Microsoft grants to you a personal, nonexclusive license to use the Software, and to make and use copies of the Software, provided that for each individual using the Software within your organization, you have acquired a separate and valid license for each such individual.

Sunday, January 04, 2009

Web-pages that looked good in IE6 look bad in IE7

If you have found this post while performing a search on Google, then you or your organization recently upgraded to Internet Explorer 7 (IE7) from Internet Explorer 6 (IE6) and you suddenly found some or all your web-pages look terrible in IE7.

In most of the pages, divs and panels were cutting off and not displaying their entire contents. In other cases fonts looked bigger or table cells seemed to have more space around their contents. In the beginning it just did not make sense as to why the pages were looking bad in IE7 while they worked in IE6 for ages. And then I found out that IE7 has been made to be a more standards compliant browser (IE7 and standards compliance). Which meant that IE6 was not a standards compliant browser and that, it would turn out, would be the cause of the problem.

The problem of cut of divs and panels in my web-pages was due to the way in which IE6 interprets the height property: IE6 interprets the height as the minimum height property for the elements. For some reason, a number of pages in my site had div and panel elements with invalid height values such as 1px. This I think was due to the Visual Studio 2005 web-designer. When viewed in IE6, these elements looked fine, this was because IE6 was disregarding the height element and interpreting it as though it were a minimum height for the element, which meant that it would show all of the content inside the element. But when the same page was viewed in IE7 (which interprets the height correctly, as THE height for the element), the elements were cutting off the content that fell outside of the height value.

So how do you fix these problems?

There are couple of solutions available: setting IE7 to render pages just like IE6 would, or fixing the elements so that they show up correctly in all browsers.

Solution 1: Making IE7 HTML renderer behave like IE6’s renderer

First a quick introduction to “Quirks” mode. Almost all browsers contain a rendering mode called the Quirks mode. According to this article in Wikipedia:

“Quirks mode refers to a technique used by some web browsers for the sake of maintaining backward compatibility with web pages designed for older browsers, instead of strictly complying with W3C and IETF standards in standards mode.”

So what we need is a flag to tell IE7 that we would like it to display a web-page in Quirks mode.

Lets first take a look at an example web-page that has been designed in Visual Studio 2005.

 Web-page in VS 2005's Web-designer As you can see, Visual Studio 2005’s web-designer displays the page correctly.

But when the page is viewed in IE7, the result is that the web-page gets pretty badly mangled.

Web-page without fixes in IE7

It turns out that IE7 determines on which rendering engine (standards or quirks) to use to display a web-page by looking at the DOCTYPE declaration for that page. In the case of my sample web-page shown above the html includes the following DOCTYPE definition:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

IE7 looks at this doctype tag and decides to display the page in “Standards” mode.

To make IE7 use “Quirks” mode to display the page, all we need to do is add a comment tag before the DOCTYPE tag:

<!-- -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

This flags IE7 to turn on its quirks mode rule set while rendering the web-page. If you look at the web-page in IE7 now, it will look very close to the page that was designed in VS 2005.

Web-page viewed in IE7 using Quirks mode

My thoughts about using Quirks Mode:

Getting IE7 to display pages in quirks mode so as to make the web-page look like it used to in IE6 using the comment tag before the DOCTYPE tag is a quick and dirty solution. The reason that I say dirty are 4 fold:

1. You are only masking the problem, by making Internet Explorer go back to its bad days of not adhering to the W3C standards.

2. Your pages will not display correctly in other standards compliant browsers (future IE versions, FireFox, Google Chrome, etc.).

3. You are relying on Microsoft correctly implementing the quirks mode to display your web-pages correctly.

4. Depending on the types of CSS used on your elements, Quirks mode may or may not fix your problems. (for example on some of my pages, margins in cells got exaggerated in IE7’s quirks mode, making the page look terrible, even though other elements looked fine).

Notes: If you decide on using this solution, I suggest that you put a comment in between the comment tags, that will make it easy to find all the pages where you are flagging IE7 to use quirks mode, thus allowing you to come back at a later time and fix the pages for good. I use <!--TODO: Fix IE7 Quirks Mode Requirement-->

Solution 2: Fix the problem

Like I said before, solution 1 is a quick and dirty fix that one can use to get their pages to display correctly in IE7. But this is definitely not my preferred way of fixing this issue. In my opinion, it is always better to fix the root cause of the problem whenever possible, instead of using something that covers up the problem. The biggest benefit to fixing the problem is that your pages will appear correctly in all future versions of Internet Explorers as well as other browsers such as FireFox and Chrome.

But unfortunately the problem is not easy to fix using Visual Studio 2005. This is because VS 2005’s web-designer uses the same rules that IE6 used to render content and hence displays pages differently when compared to IE7. So you will have to do one of the following to fix the problem:

1. Fix pages blind: Once you know what elements are causing the problem, you will have to go through the HTML and fix the styling properties on those elements. In my sample web-page, this would be easy as all I would have to do is remove the height properties on the div elements. But in reality this will not be easy to do on an entire site, as you will have many different types of problems that will have to be fixed and many of them will have to be fixed simultaneously. Not knowing what the result will look like in the designer, you will be forced to go through many, many iterations of manipulating the HTML and viewing the results in IE7. I definitely do not recommend this route. If you are stuck with VS 2005, then you are probably better of trying to use Quirks mode.

2. Get VS 2008: Visual Studio 2008’s web-designer uses the same set of rules that IE7 uses when displaying web-pages. This means that what you see in VS 2008 is what you see in IE7 (the following screen shot shows the web-page as displayed by VS 2008’s web-designer before any fixes were applied).

image

Because the designer shows the page with all its problems, it becomes extremely easy to fix the page’s issues.

Web-page in VS2008 after fixes have been applied. Fixed web-page in IE7
image image

Notes: VS 2008’s web-designer does not know what quirks mode is, so even if you use the comment before DOCTYPE tag trick, the page will be displayed in the designer as though it were in standards mode. Also, I found that the web-designer seems to treat the height property on some elements (such as drop down lists) as though it were the min-height property for that element. These elements will appear correctly in the web-designer, but will look wrong in IE7.

The following JavaScript can be used to determine if a page is being displayed in Quirks mode or Standards mode.

javascript:m=(document.compatMode=='CSS1Compat')?'Standards':'Quirks';window.alert('You%20are%20in%20'%20+%20m%20+%20'%20mode.');

Or, just drag the following link/bookmarklet on to your links toolbar or save it to your bookmarks Q or S Mode. Clicking it will display whether the page is being displayed in quirks mode or standards mode.

Final Note: This problem should make it clear how important it is to use CSS for the formatting of the pages in your web-site. This is because, if you used CSS, then it would become extremely easy to fix the problems by fixing the CSS in one central place (your CSS file). If you did not use CSS, then you will have to fix each page individually. Furthermore, if you used an external CSS file, it will make it easy for you to use hacks to make your page display correctly across different web-browsers.

References:

IE8, standards compliance and interoperability: http://blogs.msdn.com/ie/archive/2008/03/03/microsoft-s-interoperability-principles-and-ie8.aspx

IE7 and standards compliance: http://blogs.msdn.com/cwilso/archive/2006/08/10/694584.aspx

List of IE CSS bugs: http://www.positioniseverything.net/explorer.html

A fix for the IE6 height bug: http://www.webmasterworld.com/css/3128123.htm

Wednesday, December 31, 2008

Crystal Reports Basic 2008 Runtime Installer

Need the Crystal Reports Basic 2008 run-time installer? Find it in the following folder on the development machine.

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\CrystalReports10_5

More Info: http://msdn.microsoft.com/en-us/library/ms225231.aspx

Copy and run the installer on the machines where you plan on deploying your application.

Crystal Reports Basic 2008 is the version of CR that is bundled with Visual Studio 2008.

important note: The correct method of deploying CR 2008 Basic is to create your installer correctly. If done correctly VS will include all the dependencies required by your application, including the CR dlls. This is typically done by including the CR merge module installer.

Read more at http://msdn.microsoft.com/en-us/library/ms227351.aspx

Note 2: The runtime installer for Crystal Reports for Visual Studio 2005 can be found at

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\CrystalReports

More Links….

https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/40c0aa01-5a64-2b10-11a8-eef191b91316

Monday, December 29, 2008

Visual Studio Icons

I needed VS icons that would allow me to differentiate between the different versions of Visual Studio that I have installed on my machine (I have VS 2005 and VS 2008 installed side-by-side).

Here is what I managed.
image

The different icons are available in the following dll "%ProgramFiles%\Common Files\Microsoft Shared\MSEnv\VSFileHandler.dll"

Here are the icons that are available in the dll.

image

Wednesday, December 17, 2008

Log4Net: Unable to send emails to multiple addresses

The SMTPAppender is supposed to be able to send log information to an email addresses that is specified in the To property.

Here is a basic configuration for the SMTPAppender for the config file.

<appender name="SmtpAppender" type="log4net.Appender.SmtpAppender">
            <to value="toEmailAddresses"/>
            <from value="fromEmailAddresses"/>
            <subject value="subject"/>
            <smtpHost value="smtpHostAddress"/>
            <bufferSize value="1"/>
            <lossy value="true"/>
      <evaluator type="log4net.Core.LevelEvaluator">
        <threshold value="WARN"/>
        <!--<threshold value="ERROR"></threshold>-->
      </evaluator>
      <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%newline%date [%thread] %-5level %logger [%property] - %message%newline%newline%newline"/>
      </layout>
</appender>

Based on the SMTPAppender documentation, one should be able to send emails to multiple addresses and this is to be done by using the semi-colon as the delimiter. (documentation)

But if you try and do this, LOG4Net will decide to no longer send an emails. This was perplexing as, when I used a single email address Log4Net would correctly send out an email. But if I tried sending an email to multiple recipients, Log4Net would not send out an email.

After some testing, I found out that the correct delimiter in this case is supposed to be the COMMA (,) and not the semi-colon!

Now you know!

One issue I had while using the Log4Net API was that it seemed to be swallowing up exceptions that were occurring within it. That seemed to be the most logical explanation about what was going on with the multiple email addresses de-limited by semi-colons.

Here is useful information on how you can set Log4Net to emit it's trace information - which can be useful in tracking down these errors.

How do I enable log4net internal debugging?

2 methods are available to turn on internal debugging:

  • via the application's configuration file
    <configuration>....
        <appSettings>
            <add key="log4net.Internal.Debug" value="true"/>
        </appSettings>
    </configuration>
  • set the static log4net.Util.LogLog.InternalDebugging property to true.

Debug messages are written to the console. So for an ASP.net app or a windows forms based app you might think you are out of luck. But here is another little trick.

You can redirect data sent to the console to a file or another application. When the application that is using Log4Net is attached to a debugger, the console information is automatically captured to the output window. But if it is not then you can use a tool like DebugView to capture the output from Log4Net.

To capture Log4Net's trace information to a file you need to add the following information under the configuration node of the application's config file.

<configuration>
    ...
    <system.diagnostics>
        <trace autoflush="true">
            <listeners>
                <add 
                    name="textWriterTraceListener" 
                    type="System.Diagnostics.TextWriterTraceListener" 
                    initializeData="C:\log4net.txt" />
            </listeners>
        </trace>
    </system.diagnostics>
    ...
</configuration>

Wednesday, December 10, 2008

PageRequestManagerServerErrorException with Status Code 401

The error "Sys.WebForms.PageRequestManagerServerErrorException: An unknown error occurred while processing the request on the server. The status code returned from the server was: 401", is due to a permissions issue. One can determine that by checking on the 401 error code.

In my case it was because a method on one of my web pages needed to have write access to folder where it created temporary images. Without the permission the browser would throw this generic error message. If you ran the page on a browser on the actual server, you would get the actual error message - which in my case clearly pointed to the fact that I did not have write access to the folder I was trying to write the images to.

Once the User account was given write access to that folder, the problem went away!

Friday, November 21, 2008

Using the Microsoft Lines of Code Counter Tool

If you download the MS LOC counter tool (available at http://technet.microsoft.com/en-us/library/bb897860.aspx) and then install the add-in version, you might be left wondering about how to start using the tool (at least I was!)

Before installing the MS LOC tool make sure that you have VS 2005 and Team Explorer installed on your machine. (Not sure if MS-LOC works without Team Explorer).

To start using the tool first go to View -> Other Windows -> LOC Counter Explorer.

image

This will bring up the LOC Counter Explorer tool.

image

Next you need to create a counter task and then run it.

The MS-LOC tool allows you to count code that might be stored in Visual Studio Team System or Visual Source Safe repository or even items that are stored on your file system (choice is mutually exclusive though).

For more information:

Notes
Note on IT
PowerPoint
PowerPoint Presentation
Podcast
IT Pro Webcast, WMA, MP3
TechNet Radio
Download the tool
Line Of Code Counter tool