All of us heard of the upcoming ASP.Net 4.0 and Visual Studio 2010 due in Q4 2009 so I thought on listing the highlights on the ASP side. You can find the original whitepaper here.

 

Core Services

   Extensible Output Caching - adds an extensibility point to output caching that enables you to configure one or more custom output-cache providers

   Auto-Start Web Applications - The auto-start feature provides a controlled approach for starting up an application pool, initializing an ASP.NET application, and then accepting HTTP requests

   Permanently Redirecting a Page - adds a new RedirectPermanent helper method that makes it easy to issue HTTP 301 Moved Permanently responses

   The Incredible Shrinking Session State - introduces a new compression option for both kinds of out-of-process session-state providers. When the compressionEnabled configuration option is set to true, ASP.NET will compress (and decompress) serialized session state by using the .NET Framework System.IO.Compression.GZipStream class.

 

AJAX Functionality in ASP.NET 4.0

   Client Template Rendering - includes a new template engine for client development that meets the following requirements:

  • Performance — The engine must be able to render a typical number of items using a reasonably complex template before users perceive an interruption in their interaction with the application.
  • Simplicity — The template syntax must be very readable and must be optimized for the most common scenario, namely one-way/one-time binding.
  • Expression language — Templates must support an expression language to go beyond the simplest cases.
  • The expression language should use familiar syntax, ideally JavaScript syntax.
  • Interspersed code and markup — It must be possible to perform conditional rendering or to loop over markup by using code that surrounds HTML.
  • XHTML compliance — The template should be able to render XHTML-compliant markup.
  • Components — When using the template syntax, the developer must be able to instantiate client-side controls and behaviors that attach to HTML elements in the page or within templates

   Instantiating Behaviors and Controls Declaratively -  introduces a way to declaratively instantiate client-side controls and behaviors and attach them to HTML elements

   Live Data Binding - ensures that the target value is automatically updated whenever the source value changes

   Using the Observer Pattern with JavaScript Objects and Arrays - The observer pattern enables an object to be notified about changes that occur in another object. (The term observer pattern is often misused in JavaScript frameworks to describe event handling based on the addHandler method and similar techniques.) ASP.NET 4.0 implements the pattern completely

   The DataView Control - The DataView control can bind to any JavaScript object or array, or to any ASP.NET AJAX component

   The AdoNetServiceProxy Class - enables read-write interaction with ADO.NET Data Services from JavaScript

   The DataContext and AdoNetDataContext Classes - provides full support for change tracking in the browser. This enables complete end-to-end AJAX-based data scenarios

   Refactoring the Microsoft AJAX Framework Libraries - one can now choose whether to load all the javascript libraries or only part of them throught the ScriptManager

 

Web Forms

   Setting Meta Tags with the Page.Keywords and Page.Description Properties - One of the smaller additions that has been made to ASP.NET 4.0 Web Forms is the addition of two properties to the Page class, Keywords and Description. These two properties represent corresponding meta tags in your page

   Enabling View State for Individual Controls - In ASP.NET 4.0, Web server controls include a ViewStateMode property that gives you control-level granularity over whether view state is enabled. This lets you disable view state by default and then enable it only for the controls that require it in the page

   Changes to Browser Capabilities - includes a feature referred to as browser capabilities providers. As the name suggests, this lets you build a provider that in turn lets you use your own code to determine browser capabilities

   Routing in ASP.NET 4.0 - built-in support for using routing with Web Forms

   Setting Client IDs - The new ClientIdMode property addresses a long-standing issue in ASP.NET, namely how controls create the the id attribute for elements that they render

   Persisting Row Selection in Data Controls - Persisted selection is now supported for the GridView and ListView controls in all projects by using the PersistedSelection property

   FormView Control Enhancements - A new RenderTable property is now available that lets you specify whether the FormView control renders using a table

   ListView Control Enhancements - ListView control does no longer require a layout template.

   Filtering Data with the QueryExtender Control - To make filtering easier, a new QueryExtender control has been added in ASP.NET 4.0. This control can be added to EntityDataSource or LinqDataSource controls in order to filter the data returned by these controls. Because the QueryExtender control relies on LINQ, the filter is applied on the database server before the data is sent to the page, which results in very efficient operations

 

Dynamic Data

   Declarative DynamicDataManager Control Syntax - The DynamicDataManager control has been enhanced so that you can configure it declaratively, as with most controls in ASP.NET, instead of only in code

   Entity Templates - Entity templates offer a new way to customize the layout of data without requiring you to create a custom page. Page templates use the FormView control (instead of the DetailsView control, as used in page templates in earlier versions of Dynamic Data) and the DynamicEntity control to render Entity templates. This gives you more control over the markup that is rendered by Dynamic Data

   New Field Templates for URLs and E-mail Addresses - ASP.NET 4.0 introduces two new built-in field templates, EmailAddress.ascx and Url.ascx. These templates are used for fields that are marked as EmailAddress or Url with the DataType attribute

   Creating Links with the DynamicHyperLink Control - Dynamic Data uses the new routing feature that was added in the .NET Framework 3.5 SP1 to control the URLs that end users see when they access the Web site. The new DynamicHyperLink control makes it easy to build links to pages in a Dynamic Data site

   Support for Inheritance in the Data Model - Dynamic Data has been modified to understand inherited objects in the data model and to support scaffolding for the inherited tables

   Support for Many-to-Many Relationships (Entity Framework Only) - New ManyToMany.ascx and ManyToMany_Edit.ascx field templates have been added to provide support for displaying and editing data that is involved in many-to-many relationships

   New Attributes to Control Display and Support Enumerations

   Enhanced Support for Filters

 

Visual Studio 2010 Web Designer Improvements

   Improved CSS Compatibility - The Visual Web Developer designer in Visual Studio 2010 has been updated to improve CSS 2.1 standards compliance

    HTML and JScript Snippets - In Visual Studio 2010, IntelliSense snippets are supported for JScript, alongside C# and Visual Basic, which were supported in earlier versions of Visual Studio

   JScript IntelliSense Enhancements - JScript IntelliSense has been redesigned to provide an even richer editing experience. IntelliSense now recognizes objects that have been dynamically generated by methods such as registerNamespace and by similar techniques used by other JavaScript frameworks. Performance has been improved to analyze large libraries of script and to display IntelliSense with little or no processing delay. Compatibility has been dramatically increased to support nearly all third-party libraries and to support diverse coding styles. Documentation comments are now parsed as you type and are immediately leveraged by IntelliSense 

Web Application Deployment with Visual Studio 2010

   Web Packaging - Visual Studio 2010 uses the MSDeploy tool to create a compressed (.zip) file for your application, which is referred to as a Web package. The package file contains metadata about your application plus the following content:

  • IIS settings, which includes application pool settings, error page settings, and so on.
  • The actual Web content, which includes Web pages, user controls, static content (images and HTML files), and so on.
  • SQL Server database schemas and data.
  • Security certificates, components to install in the GAC, registry settings, and so on.
  • A Web package can be copied to any server and then installed manually by using IIS Manager.
  • Alternatively, for automated deployment, the package can be installed by using command-line commands or by using deployment APIs.

   Web.Config Transformation - For Web application deployment, Visual Studio 2010 introduces XML Document Transform (XDT), which is a feature that lets you transform a Web.config file from development settings to production settings

   Database Deployment - A Visual Studio 2010 deployment package can include dependencies on SQL Server databases. As part of the package definition, you provide the connection string for your source database. When you create the Web package, Visual Studio 2010 creates SQL scripts for the database schema and optionally for the data, and then adds these to the package. You can also provide custom SQL scripts and specify the sequence in which they should run on the server. At deployment time, you provide a connection string that is appropriate for the target server; the deployment process then uses this connection string to run the scripts that create the database schema and add the data

   One-Click Publishing - Visual Studio 2010 also lets you use the IIS remote management service to publish a Web application to a remote server. You can create a publish profile for your hosting account or for testing servers or staging servers. Each profile can save appropriate credentials securely. You can then deploy to any of the target servers with one click by using the Web One Click Publish toolbar. With Visual Studio 2010, you can also publish by using the MSBuild command line. This lets you configure your team build environment to include publishing in a continuous-integration model

I just finished modding my computer with the goal of making it more silent. It all started with an Antec Sonata III 500 which was supposed to hold my new Core2Duo. I like this case. Sturdy build and quite heavy. It has springs for the harddrive mounts to dampen the shocks and sound, a good 500Watt source and gorgeos looks and also it is very easy to work with, especially with me poking my head inside it to check and modify stuff.

 At that time I stuck with the Intel stock cooler which of course proved too loud. From the perfomance it was ok. I am not an overclocker so it was enough for the job. Still I needed to change it because it was loud as hell. I chose A Scythe Ninja 2 which can normally be used also in a fanless mode but I did not risk and installed also the provided fan, which is a 120×120 - 800rpm one (very quiet also).

My shock was of course that my system was as loud as before so I turned my head to the cooler on the VGA. This was a Saphire 4850 with a Zalman cooler; Noisy as hell as I saw, and thus I had to go for yet another upgrade which turned to be an Arctic Accelero S1 Rev.2. Also this is designed as a fanless sollution but again I wanted to play safe and added the turbo module which consists of 2 low rev fans barely audible.

All in all the system is now quiet and yet powerfull to play anything I throw at it. I could not make it dead silent but its miles from where it started. Below are some pictures I took along the process.

Scythe Ninja 2

Scythe Ninja 2

Arctic Accelero S1 Rev.2 + Turbo module
Arctic Accelero S1 Rev.2 + Turbo module
Final view - don't mind the cables ... subject for new mod soon

Final view - don't mind the cables ... subject for new mod soon

It’s been again a long time since my last post.
Today I wanted to explore a little bit the realms of paralel processing. As I already stated in some previous posts, the current trend of going multicore is somewhat out of phase of the current programming techniques, meaning we have multicore but we rarely use it. Most applications available on the market are single core and some have just some modules optimized for multicore.
Suprisingly the most parallel applications nowadays are graphics processing. Latest generation GPU’s are actually multicore processors, but specialized for simple operations (thus very fast). For the general purpose software developer this processing powerhouse is out of reach due to the different programming model. What this means is that first of all there is a lack of higher level abstractions of the GPU and also there are limitations because of this specializations.
There are some API’s available from NVIDIA and AMD (read ATI) in the form of CUDA and STREAM, but for me, as a C# developer they are not attractive since they offer a C++ API.

Fortunately there is Microsoft Accelerator which you can get from here. This is a .Net abstraction over the GPU and allows for some basic computations to be forwarded to the GPU instead of the CPU. Naturally I wanted to explore a little bit and especially to do some tests. Below is my test example, some results and remarks.

using System;

using Microsoft.Research.DataParallelArrays;

 

namespace MSAccelerator

{

    class Program

    {

        public const int dimension = 5000;

        public const int repetitions = 1000000;

 

        static void Main(string[] args)

        {

            Microsoft.Research.DataParallelArrays.ParallelArrays.InitGPU();

            float[] matrix1 = new float[dimension];

            float[] matrix2 = new float[dimension];

            float[] matrix3 = new float[dimension];

 

            using (Timer t = new Timer())

            {

                Console.Out.WriteLine(“Starting generating the source matrices”);

                Random r = new Random((int)DateTime.Now.Ticks);

                for (int i = 0; i < dimension; i++)

                {

                    matrix1[i] = (float)(r.NextDouble() * 1000);

                    matrix2[i] = (float)(r.NextDouble() * 1000);

                }

                Console.Out.WriteLine(“Finished generating the source matrices.

                  Time taken (ms) :” + t.Milliseconds.ToString());

            }

 

            using (Timer t = new Timer())

            {

                Console.Out.WriteLine(“\nStarting adding the two the source matrices”);

                for (int k = 0; k < repetitions; k++)

                {

                    for (int i = 0; i < dimension; i++)

                    {

                        matrix3[i] = matrix1[i] + matrix2[i];

                    }

                }

                Console.Out.WriteLine(“Finished adding the two the source matrices.

                  Time taken (ms) :” + t.Milliseconds.ToString());

            }

 

            // transfer the data in structures than can be used by the accelerator

            DisposableFloatParallelArray pmatrix1 = new DisposableFloatParallelArray(matrix1);

            DisposableFloatParallelArray pmatrix2 = new DisposableFloatParallelArray(matrix2);

            DisposableFloatParallelArray pmatrix3 = new DisposableFloatParallelArray(matrix3);

 

            using (Timer t = new Timer())

            {

                Console.Out.WriteLine(“\nStarting adding the two the source

                  matrices using the GPU”);

                for (int k = 0; k < repetitions; k++)

                {

                    object result = ParallelArrays.Add(pmatrix1, pmatrix2);

                }

                Console.Out.WriteLine(“Finished adding the two the source

                  matrices using the GPU. Time taken (ms) :” + t.Milliseconds.ToString());

            }

            Console.In.Read();

        }

    }

 

    public class Timer : IDisposable

    {

        private DateTime startTime;

        public Timer() { startTime = DateTime.Now; }

        public int Milliseconds

        {

            get

            {

                TimeSpan ts = DateTime.Now.Subtract(startTime);

                return (int)(ts.Ticks / 10000);

            }

        }

        public void Dispose() { }

    }

}

The code above needs some explanations. The test involved the adding of two one dimensional int arrays. The dimension of the arrays were chosen to 5000 due to memory constraints. I am unable to pinpoint now the cause but going over 10.000 elements results in a null pointer exception in the Accelerator implementation. In might have something to do with the translation of the data into the vertices matrix or a bad implementation of the library. Because of this I chose to do a repetition in order to attain long running operations (1.000.000 repetitions). Yes this is quite high but at 10.000 repetitions the execution was under 15 msec and that is also around the value of the execution of the DateTime; so I had to choose a bigger repetition number.

In the bigger picture there are 4 steps: fill the matrix with random data, compute using a standard cpu-bound algorithm, put the data into structures usable by the Accelerator, make the operations using the Accelerator.

And now the results:

  • on the cpu-bound algorithm: 36.909 msec
  • on the gpu-bound algorithm: 265 msec

This results in a 139x increase in speed. Of course this is algorithm and hardware dependant.

Test machine specs: Core2Duo 6750 2.66Ghz, 4Gb Ram DDR2, Saphire ATI 4850 512Mb stock voltages/frequency.

One more thing to be added here are the obvious limitations of GPU processing, mainly the operations possible being on scalar values (int, float, double, bool). Also the context passing from CPU to GPU is costly and you only gain tabgible benefits only on arrays larger than 1 billion.

[UPDATE]: I found also a C# implementation of CUDA. I have not had time to look at it but it looks promising. Maybe in the future I will do some test comparissons between it and MS Accelerator.

Hi,

Some days ago I read an interesting article about SSD performance degradation on Anandtech, and I kinda felt that this was happening to me also. I don’t own an SSD yet but I encountered flash performance degradation on my 8Gb Flash Voyager stick. Now I won’t go into the details about why flash performance degradation because the article above is more explanatory than I could make it. Suffice to say that I wanted to see if I can bring my stick back to life.

What was wrong with my voyager is that in the last weeks the write performance was poor. Whereas normally I could write at around 9MB/sec now I could only do it only at around 2-3MB/sec. From the article I understood that this was because even if the OS was reporting enough free space on the drive, all the space was already holding data and in order to write over it the flash needed to get the invalid data, write it to cache, delete the old location and then overwrite it with the new data. If one could delete everything from the location, subsequent writes would be just writes with no additional steps to execute, thus faster write speeds. This meant that I would need to do a format of the stick. But before that I had to do some tests to see performance before and after.

Let us see the scenario. Initially we have a full of data drive, even though the OS reported 7GB free out of 8Gb. I downloaded ATTO Disk Benchmark (I would have used HDTach but it does not work on my Windows7), and I ran a test of read/write for up to 256MB chunks. I stopped it when getting to 8Mb chunks as I saw no significant performance change going from 64K to 8Mb. You can see below the results:
before

Then I did a full format on the disk. Same FAT32 with 4096Kb allocation. The results on the write performance are in places 2.5 times greater. The read speed was the same. See below:

after

Of course format is not an action that you want to do often, as flash cells have a limited lifespan. But when a 2.5 times write performance penalty occurs I would certainly do it, especially when you really need this and paid top dollar for your flash (read Flash Voyager GT and the likes).

My testing machine specs (just so no one comes with remarks like “the test was bottlenecked somewhere”): Intel Core2Duo 6550 2.6Ghz, 4Gb DDR2 Corsair, Gigabyte P35 motherboard and a 500Gb Caviar Black HDD.

Cheers

Today I was looking on MSDN and came upon a blog entry of J.D. Meier about 8 new big trends. I must say that I agree and I want to share them also here:

  • Analytics is Hot.  “The 21st century is all about math: some of the most unique, innovative ideas are emerging with these types of analytic projects. This is where the next billion dollar industries are being born.”
  • Small is the new R&D.  “Today, the global R&D process has changed, and small is big. The global, infinite idea loop allows topic experts to share their latest research and insight with their global peers on a continuous basis. It’s a fundamental transformation in which most new scientific discoveries now percolate from the bottom up.”
  • Attitude and Amusement. “The fact is, you’ll need them. That’s why workforce engagement is the big issue — you’ll only be able to get the staff you need if you can keep them active, engaged, interested and amused. A entirely different workplace concept that is radical, yet necessary.”
  • Time Disappears.  “The major trend going forward is the collapse of time. There’s no time to plan anymore - there is just a need for action. While we still need budgets to manage and control, they’ll have to be constantly adjusted to deal with new realities. In this context, volatility is the new normal : the concept of risk management, for example, is transitioning quickly to one of risk containment.”
  • Resistance to Change Retires.  “The coming generation of senior management aggressively pursues and implements new ideas. While the first is reluctant to embrace new business models, the next steamrollers them. Expect velocity!
  • Careers End. “Your paycheck will come from: the global, itinerant, part-time, skills-for-hire economy.”
  • Knowledge & Skills Banks.  “The capital of the 21st century isn’t financial : it’s experiential knowledge that is extremely scarce and specialized.”
  • Interactivity Redefines.  “Every industry will soon be transformed by the forthcoming era of “pervasive connectivity.”  Essentially, every device and thing around us is about to become plugged in — leading us to an era of interactivity and connectivity that is mind-boggling in scope.”

One of the challenges of today’s projects is automatic tests. When we speak of automated testing we always target repeatability, meaning what we test today we must be able to test tomorrow and later. This is easy for database independent applications but when your testing functionality that modifies data you always find yourself wondering how can you ensure that when the tests start you have correct data.

Just to exemplify we will give an example. Suppose you have a table User with fields Id and Name. Your functionality needs to make an insert into this table but only if a user with the same name does not exist. You make an NUnit that tests the insert, when the tests runs a new user is inserted. But what happens when you run the second time the test? Well the insert will not execute as the user already exists. To avoid this situations you have 3 choices:

  • run a script at the end of the test that will clean up any existing data (you can do this also at the begining of the test). The main problem with this is that it is hard to maintain, especially when the database changes or there are many foreign keys involved.
  • restore a fresh copy of the db at the beginning of the test so you always have the same initial data. This is time consuming and the initial state of the database might change over time so you might have to manually maintain the “fresh” database.
  • use the rollback mechanism of the database.

If we are using NUnit and SqlServer the third choice is an easy one both in implementation and maintenance. There is a mechanism provided by TeamAgile which lets you specify that a test should have the data rolled back when the test ends. The idea is simple. When the tests starts, it informs the database that all the operations in the current thread context will be executed in a transaction and at the end it will instruct the database to do a rollback. The maintenance is eased because the database you use can be a copy of the live database and this suffers no data changes from test to test.

Now we get to the hard part. NUnit test data rollback is solved but lately all big web application also use automatic tests for the interface. The tools vary: Selenium, QTP, WatiN (our choice) or others. Now for this tests data rollback cannot be used like in the case of NUnit because each request gets it’s own thread context and all the other methods have their problems as stated above. So we get to the same problem. How can we do data rollback in automated web tests?

The solution I chose is easy, but depends on the data access layer implementation. For example we have a single point where SqlCommand’s are created and that is good because we can use transactions. The idea is simple; any time a database call is made we check if we have a transaction started and if so then we will execute the call within the existing transaction. But this is implemented in the data layer and our tests are done on the interface layer and we have to somehow connect them.

Create a special page where you  have two buttons and a textbox. One button is for starting a web transaction and one for rollback -ing a transaction. When the start button is pushed we make a call to the data layer to create a web transaction. This looks in a dictionary and gets us an unique id (i.e. an int) which will identify our transaction and this id we will show in the textbox and our tests records it for later use. Then we do our tests in the web pages like usual. When we finished we go to the same page enter in the textbox the transaction id and instruct to rollback.

I will post later some code to this so stay tuned …

Ok, this should be a nobrainer for most of C# developers, me included. Still it happened to me and believe me I was dumbstruck.
I wrote a piece of code like the one below:

namespace TestInheritance
{
public class BaseClass
{
public BaseClass(string parameter) {}
}

public class ChildClass : BaseClass
{
public ChildClass() {}
}
}

Nothing special here but on compile time you get an error: “No overload for method ‘BaseClass’ takes ‘0′ arguments“. Doh! how come? We don’t expect this to happen ussually but the little devil here is the inheritance and the non default constructor of the base class. When the constructor of the child class is called, it calls first the constructor of the base class with the same parameters. But if the compiler does detect a non default constructor it will not create the default one. So you get this error.

Cheers!

Once upon a time in Developer Land, a developer was instructed to build a page that will show the great achievements of the ancients. He diligently started to create a model and used all that he could think of in order to make it good and make its employers proud. He added text and used nice fonts and alignment tags. He used lists to enumerate battles and deeds, and images to depict the stories.

The developer was good in his work and always printed his masterpieces at InternetExplorer’s shop because they were good friends and got to know each other well. And so his latest work got printed there also and it was looking marvelous.

Unfortunately this developer never got to read all 100 Commandments passed down to developers and stopped just short of 57 where it said:

“All tags should be finished by /> or </ …>”

But his friend, the apprentice from InternetExplorer shop knew him well, and if he found a tag not looking like it should he tried to make the best out of it and it was always good.

One day the employers hired a new developer and he was good also, but this one had read the commandments and even though he did not remember them all he had a tool that checked those rules and saw that in his colleague work an <img> tag was missing the end tag and he added it. When printing it at InternetExplorer shop it was looking fine. But there was you see something wrong, as this infamous tag was looking at first like this:

<img id=”imgAchievement” >

but after the second developer with his tool had modified it, it looked like this:

<img id=”imgAchievement” alt=”" />

Now the apprentice at InternetExplorer shop saw this but did not know where is the image that he should put in place and he said to himself that the developer erred and he went about his work and everything was good.

But one day a client said “I don’t like the guys at InternetExplorer shop and I want to use FireFox shop to print” and so he did, but there the apprentice of FireFox was a genius and knew all commandments and when looking at the <img> tag, he saw it was not saying where the image was and so he went about and did what he knew was right and showed there a picture of the whole artwork. But this was not good for the customer and so they tried to fix it but the developer could not speak with the apprentice from FireFox shop because they spoke different languages and only knew what the client said and so they struggled for what seemed to be an eternity.

Then the original developer remembered that a long time ago another client used to print this work at FireFox shop and that there was no problem and so he said “Why don’t we give this customer what I gave the customer from a long time ago ?”. And this was good ’cause the print was fine and wonderful and this because of one tiny thing. The old print had the old <img> tag which the apprentice from FireFox shop saw it was wrong and incomplete and ignored the troublemaker.

But our story does not end here because the new developer was a perfectionist and his proofing tool never failed and when he saw that the model was wrong again he modified it unaware of the troubles it would bring. A while later another client went and used the FireFox shop and the problems were there again. But this one was determined to find out why, and so he took the long journey to the city where FireFox Inc. had shop and through endless discussions and sign languages he found what the problem was, and then he was struck. He did not need that <img> tag, it was not doing anything but trouble and so he removed it and that model was still printed for years to come even on the shop of Safari Inc.

Conclusion

You see young developers we all must abide by the commandments, because by them work also the print apprentices ,and while some learn our habbits and move and make shop in other countries calling themselves FireFox 2 or FireFox 3.0.3 or Internet Explorer 6.1 or 7.0 they all know the commandments. And if we make the model by those commandments we can be sure the prints are as we envision them.

Damn, I knew it would come to this … probably gonna take a holiday … :D

For the nostalgic ones here are some movies from past fallouts:

The intro from Fallout1

This is the famous “War never changes …” story from the intro of Fallout2. It took quite some time to find one that has the sound in good quality.

And finally the intro from Fallout3

Yesterday I cam across an issue while integrating a project in our CruiseControl.Net (CC). We needed a file from a project to be checked out always on the CC server. This is impossible with the current implementation of CC because when it tries to get the latest version from VSS it would crash, because the combination of parameters that CC sends to VSS is such that it cannot ignore locally checked out files.

VSS is actually called using the executable “ss.exe”. This accepts an option for the get command called “-GWS”. The problem is that the configuration section of CC does not support this parameter so we don’t have any way to tell VSS about skipping checked out files.

The solution looks simple although it caused me some headaches. You just have to  create a batch file that calls “ss.exe” with the right parameters. Below is the file:

@echo off

IF %1==history GOTO lhistory
IF NOT %1==history GOTO lget

:lhistory
“c:\Program Files\Microsoft Visual SourceSafe\ss.exe” %*
GOTO lend

:lget
“c:\Program Files\Microsoft Visual SourceSafe\ss.exe” %* -GWS
GOTO lend

:lend

@echo on

So what does this? It looks at the first parameter of the command sent by the CC and if it is “history” then it would just call the “ss.exe” with the parameters received from CC otherwise it would add another parameter “-GWS”. Why the branch? because the history command does not support the option GWS and you’d get errors.

To use this just replace the name of the executable of VSS in your ccnet.config file to use the batch file and not “ss.exe”. Like this:

<executable>c:\Program Files\Microsoft Visual SourceSafe\SS.bat</executable>

Of course this can be further improved and the idea used for other purposes.

Happy integration!