Welcome to MSDN Blogs Sign in | Join | Help

Block scoping variables

Block scoping is used mostly as by-product of using the standard blocks like try-catch, if-then, do-while etc.

However you can explicitly use blocks by unqualified { } braces. I've started using this feature to contain the variables within a function to a specific scope. This is cutting down silly mistakes during development time.

Posted by agujjar | 4 Comments

Best new VS Tip - Ctrl +-

Just picked this up from Scott on Writing .

Ctrl +- allows you to navigate through the stack of cursor positions in your VS session. Invaluable when going through multiple F12 (go to definition) in a multilayred application or any comlex debugging session. I expect to use this shortcut daily.

I used to mess around with Ctrl-KK, Ctrl-KN (bookmarks) to achieve the same result. This way is much simpler.

cheers

Posted by agujjar | 0 Comments

Data Generation

I don't normally work with a huge number of tables and do a lot of SQL work. But when I do start one of the most painful experiences is generating test data. Painful and un-rewarding. This is the data generation that is purely schema driven and does not care about the actual content of the data.

Looking around for data generation tools i stumbled upon this beauty from Red Gate software - Data Generator . I've just fooled around with the the trial version which was simple and quick. at 249 $ it strikes me as too steep for non-database specialists to splurge on personally.

Data generation tools sounds like a perfect fit for an open-source initiative with crowd sourced data for all types of industries. Anyone listening ?

Let me know if any one has free tool recommendations

Posted by agujjar | 1 Comments

Web Platform Installer Release candidate available

The Web Platform Installer (Web PI) is a simple tool that installs Microsoft's entire Web Platform, including IIS7, Visual Web Developer 2008 Express Edition, SQL Server 2008 Express Edition and the .NET Framework. Using the Web Platform Installer’s user interface, you can choose to install either specific products or the entire Microsoft Web Platform onto your computer. The Web PI also helps keep your products up to date by always offering the latest additions to the Web Platform.

download from here

Read more about it on Scott Hanselmans blog here

happy installing the installer

Posted by agujjar | 2 Comments

Never Again - The tale of a missed friday evening beer

He was just like all the other developers when the project started. His eyes gleamed at the thought of starting off on a new code base - the thrill of the first include statement. He knew excatly where the code would be located - D volume (obviously - no self respecting techie would ever use the system volume for storage ). The code would go 5 folders deep under Projects\Work\CompanyName\ProjectName\Code - no spaces. He liked his keyboard and spaces induce the dreaded two-fingered shift key combo that would slow down coding when in the command prompt.

The months passed away in whirl of multi-threading (to the tune of "do that funky coding.. geek booy") and exception chasing. Then it happened. T'was the night before UAT, and he had just put the final touches on the self-healing component of the system. In his all-knowing farsightedness, the self-healing patch download location would be the same as the host application which would get passed to the Process.Start command as a paramter - sweet.  It was all unit tested - patches were coming in just beautifully and doing their magic. 6 p/m friday - nice - beer beckoned. and then ..... one of the silly users decided to install the application ... of all the arcane locations under c:\Program <space> Files \blah <space> blah..  damn these pesky users . of course he had forgotten to sorround the command arguments with "".

Note to self -

1. Always develop against a realistic folder path with spaces in them

2. Never assume the presence of even a "C" drive.

Posted by agujjar | 1 Comments

Just out - IE 6 for WM

Its out and its... well much much nicer than the current PIE.

 

Can you have it ? -  No - it will not be made available as a seperate download for your exisitng WM devices. (Personally i dont think this is such a bad move if its not going to perform well as a seperate install). I know that i've been turned off opera on certain devices because it didn't perform well.

Developers - experience it using Windows Mobile 6.1.4 Emulator Images now available.

Some of the cool features available with Internet Explorer Mobile 6 are:

  • Improved fidelity (support for full fidelity desktop rendering)
  • Layout fixes to accommodate a mobile screen (text wrap)
  • Enhanced Script and AJAX support  (Jscript v5.7 from Internet Explorer 8)
  • Improved multimedia experience (Adobe Flash Lite 3.1 for Adobe Flash content)
  • Deeper integration with search
  • Enhanced cursor navigation model
  • Touch and gesture support – pan support
  • Multiple zoom levels
  • Easy switching between mobile / desktop versions of sites by specifying UA strings.

 

I am going to miss the old PIE - at least in India where data speeds aren't even upto 3G levels yet, loading a full blown web page with all the useless junk on them takes forever. fingers crossed 3G and IE 6 hit the market at the same time

Posted by agujjar | 3 Comments

Sync Inspector Tool - Inspecting Client DB state for pending Changes

Its been a while since I got a chance to post. I've been knee deep in developer mode - fun fun. A lot of work has been around Ado.Net Sync Services v2.

One of the issues I face during debugging Sync issues is analysis of the SQL Server CE database state. So ! Here's Inspector Synk to help me around with getting a little insight into the database state.

Just select the sdf file, and the Inspector will give you some basic (very basic) information about the tables and their pending changes status. I would imagine this could be useful in a production scenario to analyze changes left over on the client that need to be sent to the server. I have a bunch of ideas on enhancing this - Maybe over the weekend.

 

Some of the code might be of interest to people digging into the internals of change tracking in SSCE 3.5 with Sync Service.

__sysSyncArticles : internal tables that keeps a list of tables being tracked for changes along with each table's sync (excuse the resolution)

THE QUERY - to retrieve if table has pending changes or not. Its a little tedious to go into the details, but the most important part is the @LCSN which is the watermark for the last received anchor.

select count(*) from {0} Tbl where (((Tbl.__sysInsertTxBsn IS NOT NULL) AND ((Tbl.__sysInsertTxBsn NOT IN
(SELECT __systxbsn
FROM __systxcommitsequence)

AND Tbl.__sysInsertTxBsn > @LCSN) OR (exists
(SELECT __systxbsn
FROM __systxcommitsequence
WHERE tbl.__sysinserttxbsn = __systxbsn
AND __systxcsn > @LCSN)

)))
OR
((Tbl.__sysChangeTxBsn IS NOT NULL) AND ((Tbl.__sysChangeTxBsn NOT IN
(SELECT __systxbsn
FROM __systxcommitsequence)

AND Tbl.__sysChangeTxBsn > @LCSN) OR (exists
(SELECT __systxbsn
FROM __systxcommitsequence
WHERE tbl.__syschangetxbsn = __systxbsn
AND __systxcsn > @LCSN)

))))

There are the basis of Inspector Synk (yes - i insist on calling it that :-) )

 

 

hope this helps you happy syncers. Code Attached. Watch out for updates

Posted by agujjar | 2 Comments
Filed under:

Attachment(s): InspectorSynk.zip

IIS7 does not render CSS

This is because under default settings, "static content" is not installed with IIS.

 

To enable this on a Windows Server 2008 machine do the following

 

1. Fire up Server Manager

2. Select Web Server under Roles - notice that Static Content is not installed

3. Select Add Role Services from the right hand menu

 

4. Check Static content and install.

Posted by agujjar | 1 Comments

Consuming WCF Services from Compact Framework 3.5

CF 3.5 introduces support for WCF.

 

Consuming using a WCF client

To create a CF WCF client you will need to generate it using the NetCFSvcUtil tool which is available as a part of the Power Toys download

Use this tool as you would for the desktop to generate a client.

 

Limitation: CF 3.5 only support basicHttpBinding. So in the Web.Config of your Service you will need to modify the binding attribute to binding="basicHttpBinding"

 

Limitation: CF 3.5 supports only Certificate credentials. You have no way of specifying / attaching username and password credentials on your request to the server.

 

Consuming using a Web Reference

 

the exposed WCF service can also be consumed as a standard web reference. Indeed for some time, this might also be the preferred way until WCF client matures.

 

To make your WCF service amenable for this sort of consumption, add the attribute

[ServiceContract(Namespace = "YourName"), XmlSerializerFormat]

 

 Now simply add a web reference to the WCF service and you should be ready to go.

 

for more information check out these posts from Andrew Arnott

 

The WCF subset supported by NetCF

Calling WCF services from NetCF 3.5 using Compact WCF and NetCFSvcUtil.exe

What do you think of the new WCF 'Store and forward' Mail Transport?

Posted by agujjar | 0 Comments

Expanding Disk space in Hyper-V and Windows Server 2008

If you are running your Windows Server 2008 over Hyper-V, we must first make the extra space available through the Hyper-V Manager

Making space available

1. Open Hyper-V Manager on physical machine

2. Stop the target VM

3. Right-click target VM and select settings

4. Hardware > IDE Controller 0 > Hard drive

5. Edit Virtual Hard Disk

6. Choose Action > Expand

7. Enter expansion size

This is not the end of it. The disk drive on your VM internally is still only configured for the older space availability

 

Using the Available space

1. Log into target VM

2. Open Server Manager

3. Storage > Disk Management

4.right-click Disk > Extend Volume

5. Enter expansion size from available size

 

Hope this helps someone.

Posted by agujjar | 1 Comments

Microsoft Synchronization Services for ADO.NET with SQL Server 2008

Microsoft Sync Service Framework includes Sync Services for ADO.Net that allows you to "synchronize data from different sources over two-tier, N-tier, and service-based architectures. The Synchronization Services API provides a set of components to synchronize data between data services and a local store, instead of only replicating a database and its schema". I am currently working with Sync Services using SQL Server 3.5 as the client and SQL Server 2008 as the server side database to synchronize with. In this post I will detail out the implementation details on the server side, and how we can leverage the new Change tracking functionality of SQL Server 2008 for Synchronization.

Before we dig into how to do this with SQL Server 2008, lets take a look at how this was implemented in SQL Server 2005

SQL Server 2005 - using special columns and tables to track changes

When using SQL 2005 as the data store on the server side change tracking is typically done by using special columns on the tables to be synchronized that keep track of updates, inserts and deletes timestamps on the table. An additional _tombstone table is required to hold deleted rows. Sync Services ADO.Net provides support for this design with SqlSyncAdapterBuilder class which accepts these columns names as input parameters to build up the SqlSyncAdapter to track changes and apply inserts, updates and deletes to the server side. This design serves the needs of synchronization, but enforces the use of special columns and table just for synchronization and clutters the business abstraction in the DB with sync implementation details.

NEW SQL Server 2008 - Out of the box Change Tracking

The Nov CTP release of SQL Server, introduces an in built change tracking mechanism that is invaluable for synchronization scenarios. The documentation for this release is still sketchy and incomplete, but a good starting point is the MSDN reference.

When change tracking is enabled, the SQL Server engine maintains information about changes made to the table internally. The tracked data is made accessible by a bunch of system functions that allow you to query the information. However, remember that this does not provide full out data logging and only maintains the primary keys changes and type for change.

Database Configuration

Change tracking must be turned on explicitly on the database and on the tables that are to be tracked

ALTER DATABASE [Database_Name]

SET CHANGE_TRACKING = ON

(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON)

 

ALTER TABLE [Table_Name]

ENABLE CHANGE_TRACKING

WITH (TRACK_COLUMNS_UPDATED = ON)

More...

Important: the tracking begins for data modified after these commands are fired. This means that data that is already present in the table is viewed as seed data and will not be available through the change tracking functions.

Accessing Tracked Data

When change tracking is enabled for the database a version number is maintained internally for the database and can be accessed by calling CHANGE_TRACKING_GET_CURRENT_VERSION(). On initialization, all the rows are assigned (virtually and internally) this version number.

Whenever a DML statement is executed on any of the tracked tables, the database version number is incremented by 1, and the new row is now assigned the new version number. The old rows are still marked with the old version number. The appeal of this scheme is in its simplicity.

The CHANGETABLE function retrieves the tracked information. There are 2 ways to use this function -

1. SELECT * FROM CHANGETABLE ( Changes <Table_Name>, last_sync_version)

this returns the all the rows that have changed for the table since "last_sync_version". Each rows corresponds to one changed row in the table and contains the primary key of the row and operation.

2. SELECT * FROM CHANGETABLE ( Version <Table_Name>,  <primary_column_name>, <value>)

this is used to return the version information for a particular row

Integrating with Sync Services

Basically the Sync Service API requires that you configure a DbServerSyncProvider for your specific data store, and a SqlSyncAdapterBuilder per table to perform synchronization. A full implementation of this using SQL Server 2005 is described here A Synchronization Services Application (SQL Server 2005)

Shown below is how you would set this up using the change tracking feature of SQL 2008.We need to configure a bunch of the commands on these to enable synchronization.

DbServerSyncProvider.SelectNewAnchorCommand :contains the query to retrieve the new anchor value from the database. The anchor defines the upper bound for the set of changes to be synchronized during the current session. We will set this to the value returned by change_tracking_current_version()

DbServerSyncProvider _serverSyncProvider = new DbServerSyncProvider();

SqlCommand selectNewAnchorCommand = new SqlCommand();

string newAnchorVariable = "@" + SyncSession.SyncNewReceivedAnchor;

//SQL Server 2008 supports change_tracking_current_version() that returns
//the latest version number for the database
selectNewAnchorCommand.CommandText =
"SELECT " + newAnchorVariable + " = change_tracking_current_version()"

selectNewAnchorCommand.Parameters.Add(newAnchorVariable, SqlDbType.Int);

selectNewAnchorCommand.Parameters[newAnchorVariable].Direction = ParameterDirection.Output;

_serverSyncProvider.SelectNewAnchorCommand = selectNewAnchorCommand;

SyncAdapter.SelectIncrementalInsertsCommand: query that is used to retrieve inserts made in the server database since the last synchronization.

//select inserts from the server
SqlCommand incrementalInsertCommand = new SqlCommand();

incrementalInsertCommand.CommandText = String.Format(
@"SELECT {0} FROM {1} as originalTable
INNER JOIN ChangeTable(changes {1}, {2} ) ct
ON ct.{3} = originalTable.{3}
where ct.SYS_CHANGE_OPERATION = '{4}'
", columns, tableName, "@" + SyncSession.SyncLastReceivedAnchor, idColumnName, OPERATION_INSERT);

incrementalInsertCommand.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt);

syncAdapter.SelectIncrementalInsertsCommand = incrementalInsertCommand;

SyncAdapter.SelectIncrementalUpdatesCommand: query that is used to retrieve updates made in the server database since the last synchronization.

//Select updates from the server.
SqlCommand incrementalUpdateCommand = new SqlCommand();

incrementalUpdateCommand.CommandText = String.Format(
@"SELECT {0} FROM {1} as originalTable
INNER JOIN ChangeTable(changes {1}, {2} ) ct
ON ct.{3} = originalTable.{3}
where ct.SYS_CHANGE_OPERATION = '{4}'
", columns, tableName, "@" + SyncSession.SyncLastReceivedAnchor, idColumnName, OPERATION_UPDATE);

incrementalUpdateCommand.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt);

syncAdapter.SelectIncrementalUpdatesCommand = incrementalUpdateCommand;

SyncAdapter.SelectIncrementalDeletesCommand: query that is used to retrieve deletes made in the server database since the last synchronization

//Select deletes from the server.
SqlCommand incrementalDeleteCommand = new SqlCommand();

incrementalDeleteCommand.CommandText = String.Format(
@"SELECT originalTable.{0} FROM {1} as originalTable
INNER JOIN ChangeTable(changes {1}, {2} ) ct
ON ct.{0} = originalTable.{0}
where ct.SYS_CHANGE_OPERATION = '{3}'
", idColumnName, tableName, "@" + SyncSession.SyncLastReceivedAnchor, OPERATION_DELETE);

incrementalDeleteCommand.Parameters.Add("@" + SyncSession.SyncLastReceivedAnchor, SqlDbType.BigInt);

syncAdapter.SelectIncrementalDeletesCommand = incrementalDeleteCommand;

 

happy sync'ing

Posted by agujjar | 1 Comments

WebBrowser control bug in Compact Framework for WM Standard device

Here's the scenario - You have a form (StartForm) which has a sub-form (subForm) that contains a WebBrowser control. When the sub-form is disposed (not just dismissed), your startform also shuts down. This is a bug !

This occurs because the Web browser control does a PostQuitMessage() upon receiving a WM_CLOSE message. Now the tricky bit over here is that a PostQuitMessage is not a real message that is inserted into the thread's message queue. Its a virtual message that will be presented to whoever cares once all messages in the queue are processed. What this means to us is that since the control is calling PostQuitMessage, we do not have a deterministic point to handle this message.

However, the workaround options are

 

  1. Don't shut the sub-form: In the code below, if you can eliminate "suForm.Dispose()" , then you don't have an issue. However, your application design may not allow this workaround.in which case, do option
  2. Handle the message pump in the StartForm by creating a message loop that exits on seeing the WM_QUIT event.

Lazy pseudo code -

SubForm subForm = new SubForm();
subForm.ShowDialog();
subForm.Dispose();  //this is the line that causes the WebBrowser to PostQuitMessage

PostQuitMessage(0); // This is to handle the future where the quit message may not be posted by the native control

//message loop that will stop once WM_QUIT (0) is presented to it

MSG msg;// Native structure coredll.dll
while (GetMessage(out msg, new IntPtr(0), 0, 0) != 0)
{
TranslateMessage(ref msg); // Native function coredll.dll
DispatchMessage(ref msg);// Native function coredll.dll
}

Posted by agujjar | 2 Comments

VS 2008 renders Windows Mobile Form as a Windows Desktop form !

Ran into a funny problem with Visual Studio, where it got confused and started rendering my Windows Mobile form as a Windows Desktop

  instead of  

The problem occurs, in my case, due to a combination of two factors

1. This form is inherited

2. Both the forms are localizable = true and have more than one localized resource files

I fiddled with the language and it started rendering correctly. Closed and reopened, the wrong display was back again. Weird !

Still trying to figure out the exact cause of this - its not easily reproducible.. ah well .. some rainy day..

Posted by agujjar | 0 Comments

Determine the Platform in .Net Compact Framework 3.5

.Net CF 3.5 introduces the SystemSettings.Platform property in Microsoft.WindowsCE.Forms namespace which provides you the platform of the device the code is executing on. The property is of type WinCEPlatform  enumeration which contains the members

  • WinCEGeneric
  • PocketPC
  • Smartphone

 The surprising bit is that since Windows Mobile 6.0, we have moved to the new taxonomy where -

  • Windows Mobile for Smartphone = Windows Mobile Standard (download the Windows Mobile 6 Standard SDK)
  • Windows Mobile for Pocket PC = Windows Mobile Classic (download the Windows Mobile 6 Professional SDK)
  • Windows Mobile for Pocket PC Phone Edition = Windows Mobile Professional (download the Windows Mobile 6 Professional SDK)

So, I'm baffled why this new enumeration is causing confusion by using the old naming conventions!
 

 

Posted by agujjar | 1 Comments

Using unsupported locale in Windows Mobile

Although you can technically change the locale of the device to anything you desire by using the SetUserDefaultLCID , you should only allow it to be set to one of the available locales. Even though your application maybe able to handle the change, this will cause instability to the system. I know for sure that atleast Pocket IE stops working with this change.

Posted by agujjar | 0 Comments
Filed under:
More Posts Next page »
 
Page view tracker