Jing - A Really Great Free Capture Tool

I stumbled across The Jinq Project last week and I think that it's just great.  I've had my eye on TechSmith's Camtasia product for a while and will eventually purchase it when I absolutely need it.  But for a 5 minute video or screen capture, Jing does the job easily.  It may even replace Vista's simple screen capture utility that I use constantly in my work.  Jing installs easily and produces SWF files for video and captures the screen for images.  The resulting file can be uploaded to ScreenCast for free, for a while, or copied to the hard drive. 

The free product (project) is over a year old, but better late than never to find a good tool.  They have so many screen capture tutorials to show how to use the already simple-to-use tool.  I let others know around the office and now they are enthusiastically using it.

-Vince

Posted by vblasberg

Visual Studio 2008 SP1

Visual Studio 2008 Service Pack 1 has finally arrived.  It is a warm welcome with the way that my Visual Studio installation "found opportunities to suddenly restart", let's say.  The SP1 installation is rather interesting, like the VS2005 service packs were.  It takes a very long time to complete, it pops up (and hides) alert windows behind the installation window, it requires the VS2008 DVD, and it requires a reboot if some applications are running such as my Yahoo messenger...  Hmmm...  So I would suggest that when installing this service pack, stay focused on its progress and start it when you don't need to get work done.

-Vince

Posted by vblasberg with no comments

DBPro How To: Initially Populating an ASP.NET Membership Database

 

With just the schema alone, the ASP.NET membership (role, profile, etc.) database does not have enough information to operate correctly.  There are a few records needed or else the ASP.NET membership and other providers will throw an error complaining that it may be an invalid version.  This is good, of course, so that the ASP.NET membership providers can innovate and the membership database will remain intact for existing application versions.  These additional records can be inserted with DBPro by adding a SQL script in the “Post-Deployment” folder under the DBPro project scripts folder.  We could name the file, “AspNet_SchemaRecords.sql”.  Also at this location, the file named Script.PostDeployment.sql must have an entry to run the post deployment SQL script.  After making these changes then deploying a new database with DBPro, an ASP.NET application should be able to connect and start using the database immediately.  Maybe in the future, this can be an option in the project wizard or available as an add-on script on the Microsoft site.


An Entry in Script.PostDeployment.sql:
 
--  Initialize ASPNET membership schema records after a complete database rebuild.
:r .\AspNet_SchemaRecords.sql

AspNet_SchemaRecords.sql:
 
USE DatabaseName; 

IF NOT EXISTS (SELECT * FROM aspnet_SchemaVersions WHERE Feature = N'common')
      INSERT INTO aspnet_SchemaVersions (Feature, CompatibleSchemaVersion, IsCurrentVersion) VALUES('common', '1', 1) 

IF
NOT EXISTS (SELECT * FROM aspnet_SchemaVersions WHERE Feature = N'health monitoring')
      INSERT INTO aspnet_SchemaVersions (Feature, CompatibleSchemaVersion, IsCurrentVersion) VALUES('health monitoring', '1', 1) 

IF
NOT EXISTS (SELECT * FROM aspnet_SchemaVersions WHERE Feature = N'membership')
      INSERT INTO aspnet_SchemaVersions (Feature, CompatibleSchemaVersion, IsCurrentVersion) VALUES('membership', '1', 1) 

IF
NOT EXISTS (SELECT * FROM aspnet_SchemaVersions WHERE Feature = N'personalization')
      INSERT INTO aspnet_SchemaVersions (Feature, CompatibleSchemaVersion, IsCurrentVersion) VALUES('personalization', '1', 1) 

IF
NOT EXISTS (SELECT * FROM aspnet_SchemaVersions WHERE Feature = N'profile')
      INSERT INTO aspnet_SchemaVersions (Feature, CompatibleSchemaVersion, IsCurrentVersion) VALUES('profile', '1', 1) 

IF
NOT EXISTS (SELECT * FROM aspnet_SchemaVersions WHERE Feature = N'role manager') 
      INSERT INTO aspnet_SchemaVersions (Feature, CompatibleSchemaVersion, IsCurrentVersion) VALUES('role manager', '1', 1)

 

Posted by vblasberg with no comments

TFS Reporting Architecture Notes

Here are some notes and a list of questions and answers regarding the TFS Reporting architecture. I gave a presentation at this month's Dallas Visual Studio Team System user group.  The topic was TFS Reporting but what we really covered was the TFS reporting architecture.  We’ll probably follow-up with a second session of “Effective TFS Reporting” to include demos and the meaning of some of the most used TFS reports. I strongly believe that the TFS Reporting architecture includes several areas that should be understood to effectively and efficiently deliver standard and custom reports. So here are some high points for the benefit of others looking for answers.

The TFS Warehouse

clip_image002

  • We avoid reporting on the operational store because it slows down everyone using the system and extra security configuration is needed.
  • Expect a slight delay when the warehouse is updated from the operational store, depending on the size of the TFS implementation. 
  •  

    The TFS Cube

    • Facts
    • Dimensions
    • Measurements

    17 fact tables in the TFSCube

    In the TFSWarehouse database, dimension tables have the field "__DimensionMemberActive" and fact tables do not. 

    Fact tables have measurement fields and foreign keys to dimension tables.

    Fact Table Examples:

    • Work Item fact table has one row for every work item stored in Work Item operational store.
    • Code Churn fact table has one row for every dimension combination.

    The 3 WorkItem Field Reportable Attributes (4 Actually)

    Fields with the reportable attribute will be exported to the data warehouse and can be included in reports. The reportable attribute takes one of three values.

    Note: Once a reportable attribute is set for a field, it can never be changed and is global to all work item types that reference the field.

    • Dimension (Integer, Double, String, or DateTime) to the warehouse database and cube as an attribute of the Work Item dimension so that the data can be used to filter reports. Work Item Type and State are good examples of a dimension.
    • Detail (Integer, Double, String, or DateTime) warehouse database in “Work Item History” and “Current Work Item” tables.
    • Measure (Integer and Double) Each measure will appear in both the Current Work Item and Work Item History measure groups. A formula is allowed for the final measurement aggregation such as Estimated work. Measure type has formula options: sub, count, distinct, count, avg, min, max
    • None Leaving a field as “None” for reportable allows it to be changed later and lessens the size of the Warehouse and Cube size.

    Ask these questions when specifying the workitem field reportable type.

    Is the field going to appear in a SQL report but not a complex calculation or summary or OLAP report? Detail
    Is the field something that will be used in a filter in an OLAP report? Dimension
    Is the field a meaningful NUMBER for calculations, a filter, and maybe a formula? Measure
    Is the field a string that can be reported in a sub-report instead of bloating the cube? Detail
    Is this just a field that is captured but never need on a report? None
    It’s uncertain how this field will be used in the future. Can only change later if it is currently “none”. None

    Resources

    Random Q & A

    Q: Can I use work item queries to perform reporting?
    A: Not exactly. Workitem queries perform an optimized query on operational data using a specialized language named Workitem Query Language. Technically you can use the same fields that the workitem query is using but the data will not be in the more optimized TFSWarehouse database. Reports that are run against the operational store will affect normal TFS operation by developers, testers, project managers, automated services, or any other TFS user. A better solution is to find the same fields in the TFSWarehouse and report on them.


    Q: How can I improve TFS reporting performance?
    A:

    1. Optimized Reports - Fewer joins and sub-reports when not needed. Use drill-downs sub-reports.
    2. Move the TFSWarehouse database to another server. http://blogs.msdn.com/vstsue/articles/774113.aspx
    3. Keep the cube smaller by specifying fields as detail and using SQL to report on them when appropriate such as string fields.


    Q: Where can I find out about known issues with TFS?
    A: Some issues can be found on the Microsoft site at http://code.msdn.microsoft.com/Project/ProjectDirectory.aspx?TagName=Hotfix,tfs. Others are reported and explained on random blog entries or the very helpful forums at http://forums.microsoft.com/MSDN.


    Q: How can I change the TFSWarehouse update period from the default of 60 minutes?
    A: This can be changed by running a web service command on the TFS application tier and specifying the number of seconds. Refer to: http://msdn.microsoft.com/en-us/library/ms244694(VS.80).aspx


    Q: Can’t use reports in Team Explorer because I have a red X Reports folder icon.
    A: This is often because of security settings, proxy servers, firewalls, host files, and security updates. Mickey Gousset wrote a good blog entry regarding this issue. http://teamsystemrocks.com/blogs/mickey_gousset/archive/2007/01/17/1312.aspx#comments


    Q: What can I do if I my OLAP cube becomes corrupted or deleted?
    A: Run the "SetupWarehouse.exe" utility with the –o option to only rebuild the cube. Then on the application tier, run the web service command, http://localhost:8080/Warehouse/v1.0/warehousecontroller.asmx?op=Run. Then on the application tier, run the web service command, http://localhost:8080/Warehouse/v1.0/warehousecontroller.asmx?op=GetWarehouseStatus until the status returned is “Idle”.


    Q: Where is the project code churn reported?
    A: The quality indicators reports to show the overall software quality. Code coverage can reported separately but is best used in a report that also contains related data such as code coverage, test results, and active bugs.


    Q: Physically, what is a cube?
    A: A set of metadata that uses a relational data store such as TFSWarehouse. When multi-dimensional data is requested, the SQL Server Analysis Server (SSAS) will read the data from the store (the TFSWarehouse database), perform analysis on it, and return it to the requester.  The retrieved data is cached and when not used after a period is discarded.  The metadata lives on the data tier in the SQL OLAP data directory such as "C:\Program Files\Microsoft SQL Server\MSSQL.2\OLAP\Data". 


    Q: I specified an incorrect reporting type for a field. What can I do to change it?
    A: Once the reportable attribute is specified to other than none and it’s used once, that is it. The simplest way is to create and use a new field with the correct report type. An alternative is to create a custom report or data file with the workitem id and the field value. Remove the field using WITField.exe to remove the field. Perform the steps to rebuild the data warehouse and the cube. Add the field using the correct reporting type. The original values can be manually entered in the workitems or a integration tool can be written to set the values.


    Q: How can I seamlessly implement my own integration into the data warehouse such as extra business intelligence metrics?
    A: The data warehouse is extensible so a managed DLL can be added to the application tier’s adapters to perform ETL operations to the data warehouse at the same intervals wherever it may be located. This provides the data in the data warehouse and the TFS Data Warehouse cube can be extended or another cube created for enhanced reporting . http://msdn.microsoft.com/en-us/library/bb286956(VS.80).aspx

    What I didn't mention is the great caching features of Microsoft's SQL Server Analysis Services for the OLAP cube when it reads from the data warehouse.  For more understanding on that topic, refer to the Microsoft webcast titled "TechNet Webcast: Real-Time Business Intelligence with SQL Server 2005 Analysis Services" as well as other great webcasts and books.

    I hope this helps others appreciate the TFS Reporting architecture.

    -Vince

    Posted by vblasberg with no comments
    Filed under:

    Silverlight 2.0 Webcasts at ISV Innovation

    Bill Lodin is presenting a very informative 4-part webcast series on Silverlight 2.0 (beta 1). 
        http://www.isvinnovation.com/Directory/Description.aspx?EventId=424

    Microsoft Silverlight 2.0


    Part: 1 - Technical Drill-down
    Part: 2 - The UI Framework
    Part: 3 - Networking Support
    Part: 4 - Advanced Topics

    We can just pretend that he dropped by for lunch to show the new features that will RTM later this year.

    -Vince

    Posted by vblasberg with no comments
    Filed under: , , ,

    How To: Unit Test a T-SQL Trigger with VSTS Database Edition

    In Visual Studio Team System Database Edition, three types of functionality are unit tested; Stored Procedures, Functions, and Triggers.  It’s not so obvious how to test a trigger and at this time there are not many examples.  This is probably because there are so many different testing needs.  Testing the trigger is very similar to the more obvious calls to stored procedures and functions.  This example shows how a trigger can be unit tested using the RAISERROR method to cause a test harness failure.  Two other methods exist to perform unit testing failures for those complicated tests. 

    1.       The Assert classes that we can use in the code-behind test classes, or

    2.       Test conditions in the Database Unit Test Designer.  These are Microsoft provided test conditions or custom written test conditions that check the test results and either pass or fail.

    In the following example, we simply count the number of records before and after the table action that causes a trigger.  We can now get the Red-Yellow-Green lights for TDD.  We might want to split this into three different tests and add transaction support.  Transaction support is added in either the T-SQL unit test as listed below or we can add it in the Visual Studio C# or VB.NET generated test code.


    The T-SQL Unit Test

    -- Database unit test for dbo.trg_CopyToHistoricalPrimaryRecords

    --

    DECLARE @beforeCount INT,

          @afterCount INT,

          @PrimaryField1 INT,

          @PrimaryField2 UNIQUEIDENTIFIER,

          @PrimaryField3 BIT,

          @PrimaryTableId INT

     

    SELECT @PrimaryField1 = 0,

          @PrimaryField2 = NULL,

          @PrimaryField3 = 0

     

    --  INSERT Trigger Test

    SET @beforeCount = (SELECT COUNT(*) FROM HistoricalPrimaryRecords);

     

    INSERT INTO [dbo].[PrimaryTable] ( [PrimaryField1], [PrimaryField2], [PrimaryField3] )

          VALUES( @PrimaryField1, @PrimaryField2, @PrimaryField3 );

     

    SET @PrimaryTableId = SCOPE_IDENTITY();

     

    SET @afterCount = (SELECT COUNT(*) FROM HistoricalPrimaryRecords);

     

    IF NOT @afterCount = @beforeCount + 1

        RAISERROR ('TRIGGER INSERT ERROR: trg_CopyToHistoricalPrimaryRecords did not insert a record in the historical table.', 1, 1);

     

    ---  UPDATE Trigger Test

    SET @beforeCount = (SELECT COUNT(*) FROM HistoricalPrimaryRecords);

     

    UPDATE [dbo].[PrimaryTable]

          SET

                [PrimaryField1] = @PrimaryTableId

          WHERE

                [PrimaryTableId] = @PrimaryTableId

     

    SET @afterCount = (SELECT COUNT(*) FROM HistoricalPrimaryRecords);

     

    IF NOT @afterCount = @beforeCount + 1

        RAISERROR ('TRIGGER UPDATE ERROR: trg_CopyToHistoricalPrimaryRecords did not insert a record in the historical table.', 1, 1);

     

    ---  DELETE Trigger Test

    SET @beforeCount = (SELECT COUNT(*) FROM HistoricalPrimaryRecords);

     

    DELETE FROM [dbo].[PrimaryTable]

           WHERE [PrimaryTableId] = @PrimaryTableId

     

    SET @afterCount = (SELECT COUNT(*) FROM HistoricalPrimaryRecords);

     

    IF NOT @afterCount = @beforeCount + 1

        RAISERROR ('TRIGGER DELETE ERROR: trg_CopyToHistoricalPrimaryRecords did not insert a record in the historical table.', 1, 1);

     

    -- PRINT '@beforeCount: ' + Cast(@beforeCount as varchar(10));

    -- PRINT '@afterCount: ' + Cast(@afterCount as varchar(10));

     

    The Trigger

    ALTER TRIGGER [dbo].[trg_CopyToHistoricalPrimaryRecords]

       ON [dbo].[PrimaryTable]

       AFTER INSERT,DELETE,UPDATE

    AS

    BEGIN

          SET NOCOUNT ON;

     

          -- UPDATE, DELETE: Capture all changes that occurred from an Insert and Delete.

          INSERT INTO [PrimaryForeignKeys].[dbo].[HistoricalPrimaryRecords]

               ( PrimaryTableId

               , PrimaryField1

               , PrimaryField2

               , PrimaryField3)

                (SELECT d.PrimaryTableId

               , d.PrimaryField1

               , d.PrimaryField2

               , d.PrimaryField3

                 FROM deleted d);

     

          --  INSERT: Capture all newly inserted records that were not from Inserts and Deletes.

          IF (0 = (SELECT COUNT(*) FROM deleted))

          BEGIN

          INSERT INTO [PrimaryForeignKeys].[dbo].[HistoricalPrimaryRecords]

               ( PrimaryTableId

               , PrimaryField1

               , PrimaryField2

               , PrimaryField3)

                (SELECT i.PrimaryTableId

               , i.PrimaryField1

               , i.PrimaryField2

               , i.PrimaryField3

                 FROM inserted i);

          END
    END

     

    Posted by vblasberg with no comments
    Filed under: ,

    The hierarchyid Data Type

    Last night’s North Dallas .Net User Group meeting was really good. Peter Debetta presented new features on SQL 2008. All of it was really interesting and will eventually be useful. I wouldn’t want to rehash all of the Microsoft documents and other blog information, but I will say that there are some useful features on the way.

    The one thing that I appreciated but felt a little pang of irritation was the new “hierarchyId” data type. I spent many a night trying to get this perfect in a past project as did Peter. This data type holds the relationship of the contained data in relation to its parent with easy access and update to Ancestors and Descendents. The one downside is that this new data type only manages trees of data and not a recursive matrix.

    I’ll jump on this feature next time I have to utilize an optimized tree of data using stored procedures. The other memorable feature is the Merge function that makes synchronizing records more natural.  It's a bit limiting but it works.

    So SQL 2008 is scheduled for release third quarter, but we know that companies are slow to adopt, even with all of the great features and the huge beta testers out there. At least sometimes we can start projects with the express versions and use these features to prove the product before production databases get converted.

    We can read more about the hierarchyid data type at:
    http://msdn2.microsoft.com/en-us/library/bb677290(SQL.100).aspx

    -Vince

    Posted by vblasberg with no comments
    Filed under: ,

    VSTS Testing - How to Get a Web Test Form Field for URL Subsequent Requests

    There are several ways to get an id from a requested form and set it as a request parameter on a subsequent web request. Remember that the querystring parameters are used on the form request before the form is retrieved and the extraction rules occur after the form has been received. This is all to ensure that the response to a formatted request was as expected.

    Option 1: Add a class that inherits from ExtractionRule and override the Extract method. This method is often required for complex logic but it's more code to maintain. We can avoid this roll-our-own method in simple circumstances.
    For a good reference, refer to Josh Christie's blog: http://blogs.msdn.com/joshch/archive/2005/11/17/494164.aspx.

    Option 2: Create, Set and Use a Web Test Context Parameter.
       

    Right-click the top node of the web test or its global "Context Parameters" context menu. Add a parameter name such as QueryStringPersonId and an initial value. If I expect to never have a value such as -2, then that is what I chose for my default in this example. This way if we ever see a -2 then the tests can report the error, create a TFS workitem or perform another task. It also makes it obvious when debugging the web test.

    Now the variable can be set and retrieved throughout the test. The value should also be available for coded tests as described previously because it's in the test context. The value can be set from a specific form field extraction.

    The context parameter can now be used in subsequent Query Strings.

       

    -VinceB

    Posted by vblasberg with no comments
    Filed under:

    On The Blog Again

    On the blog again…I just can’t wait to get on the blog again…(Willie Nelson...)

     

    I’ve been BUSY!!!  The lack of blogging over the last few months was the look of my head down getting work done.  I’ve also been working with some friends on their projects to keep my skills sharp.  I’ve been through so many things in the last year.  Most of it was product research in preparation for an enterprise architecture and a portal.  Here are a few things that I’ve spent my life on:

     
    • More work with load balanced systems and web farms
    • Consultant company research
    • Portal and Mashup Options
    • Evaluations of SalesForce.com, Microsoft CRM, CMS systems, and payment systems
    • Evaluations of Workflow Engines and Biztalk Server
     

    My personal projects also have kept me extremely busy.

    • ipDisplays – Real time IP based displays
    • And finally I created a few more DVDs for family and friends.  A big one was a slideshow of a friend’s family through the 50s, 60s, and 70s.
     

    The downside is that I feel that it’s time for me to leave ABSG.  Sometimes we just know that we can only grow by moving out (like my 19 year old son).  I investigated and brought in a great consulting company and they are so good that I’m obsolete, redundant, or something like that.  In any case, I’m not as effective as I want to be.  I’m very action oriented so I want to be in the game more than watching the game.  I still love getting under the hood but really appreciate looking at the forest more often than the trees.  I have higher standards to what I should accomplish in a year of my life for a company so it’s time to get out and make more of an impact.  ABSG is a seriously great company.  If would recommend it to anyone who’s interested.  All of these groups are great to work with.

     

    It’s not easy to leave where you know that you could just sit and work for years to come.  Thank you ABSG - one of the best companies that I’ve ever worked for.

     

    -Vince

     

    Posted by vblasberg
    Filed under:

    VSLive! Dallas 2006 - Day 1

    Day one of VSLive! Dallas 2006 came and went.  It was an all-day presentation by Rocky Lhotka covering his CSLA framework.  I used it a few years ago and was not nearly as impressed as now.  Rocky has evolved this framework to be extremely flexible, well-designed, and still free.  Add that to a day of training at DunnTraining.com to get a serious development jumpstart.  Think about it... a top consultant's help at the price of a book.  Beat that!

     

    Now I’m off to playiwith this newest version with a little CodeSmith help…

     

    http://lhotka.net

    http://www.dunntraining.com/CSLATraining.htm

    -VinceB

    Posted by vblasberg with no comments
    Filed under: , ,
    More Posts Next page »