My favorite Visual Studio 2010 Tips

by fkollmann 6/18/2010 8:35:56 PM

My favorite tips from Sara Ford's 101 Visual Studio Tips which were all new to me and I tested all of them:

Tip 2: Cycle trough the clipboard stack when pasting text by pressing Ctrl + Shift + V . This allows to past more than just the latest copied text.

Tip 8: Ctrl + , (comma) allows to get a simple type search view (like in Eclipse).

Tip 19+20: Ctrl + Alt + <arrow key> to do block select (like in the command prompt). When starting to type it allows to edit multiple lines.

Tip 37: Ctrl + F3 to search for the currently selected word.

Tip 88: Ctrl + . (dot) opens the small menu e.g. when renamed a method or variable name. No longer trying to catch that one with the mouse cursor :) .

Tip 96: Visualizer for event sender parameter in WPF.

More tips: http://blogs.msdn.com/b/saraford/archive/2010/03/30/speaking-at-devdays-2010-in-the-netherlands-visual-studio-tips.aspx

SharePoint 2010 resource files have to be complete

by fkollmann 6/17/2010 12:29:00 PM

After trying a lot of stuff on how to translate/localize XML declarations and code in SharePoint 2010, I came across a bad topic: translated resource files have to be complete!

Assuming that the following structure exists:

  • Foo.resx
    • HelloWorld –> “Hello World!”
    • ExampleTitle –> “Example”
  • Foo.de-DE.resx
    • HelloWorld –> “Hallo Welt!”

Requesting ‘ExampleTitle’ in a German web will not return the expected “Example” (as it would using compiled resources) but “$Resources:Example”.

There are two ways how resources are being requested by SharePoint:

Requesting localized string by XML declaration

These are the resource references: $Resources:<resx file base name>,<resx key>;

This results in the following error in the SharePoint log:

06/15/2010 16:57:20.06     vssphost4.exe (0x0F98)                      0x06C8    SharePoint Foundation             General                           8e25    Medium      Failed to look up string with key "<resx key>", keyfile <resx file>.    
06/15/2010 16:57:20.06     vssphost4.exe (0x0F98)                      0x06C8    SharePoint Foundation             General                           8l3c    Medium      Localized resource for token '<resx key>' could not be found for file with path: "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\<feature name>\feature.xml".    

Requesting localized string using code

I use the following method to query translations from code:

UPDATE: Due to the fact that the SPContext is not set in feature receivers when the feature is being activated using the commandline, I extended the function to be able to pass ((SPSite)properties.Feature.Parent).RootWeb:

public static class LocalizationHelpers
{
    public const string DefaultResourceFile = "<default resource name, without extension>";

    public static string GetLocalizedString(string str)
    {
        if (string.IsNullOrEmpty(str))
            throw new ArgumentException("null or empty", "str");

        return GetLocalizedStringInternal(str, DefaultResourceFile, null);
    }

    public static string GetLocalizedString(string str, SPWeb web)
    {
        if (string.IsNullOrEmpty(str))
            throw new ArgumentException("null or empty", "str");

        if (web == null)
            throw new ArgumentNullException("web");

        return GetLocalizedStringInternal(str, DefaultResourceFile, web);
    }

    public static string GetLocalizedString(string str, string file)
    {
        if (string.IsNullOrEmpty(str))
            throw new ArgumentException("null or empty", "str");

        if (string.IsNullOrEmpty(file))
            throw new ArgumentException("null or empty", "file");

        return GetLocalizedStringInternal(str, file, null);
    }

    public static string GetLocalizedString(string str, string file, SPWeb web)
    {
        if (string.IsNullOrEmpty(str))
            throw new ArgumentException("null or empty", "str");

        if (string.IsNullOrEmpty(file))
            throw new ArgumentException("null or empty", "file");

        if (web == null)
            throw new ArgumentNullException("web");

        return GetLocalizedStringInternal(str, file, web);
    }

    private static string GetLocalizedStringInternal(string str, string file, SPWeb web)
    {
        // determine language
        var lang = 1033u; // english

        if (web != null)
            lang = web.Language;

        else if ((SPContext.Current != null) && (SPContext.Current.Web != null))
            lang = SPContext.Current.Web.Language;

        // request string
        var r = SPUtility.GetLocalizedString("$Resources:" + str, file, lang);
        // enrich error string
        if (r.StartsWith("$Resources:"))
            r = string.Format("$Resources:{0},{1},{2};", file, str, lang);

        return r;
    }
}

More details: http://blogs.msdn.com/b/johnwpowell/archive/2009/11/29/sharepoint-2010-localization-with-visual-studio-2010.aspx

SharePoint 2010 ListTemplate.Name cannot be translated

by fkollmann 6/16/2010 5:35:50 PM

The whole day I was hunting an error where SharePoint 2010 refused to create a list instance (both by XML declaration and by code). All I got was either “filename invalid … 0x81020030” (XMl declaration) or NullReferenceException (by code, having the other error as inner exception when debugging).

After digging around a little bit I came across the following log message:

06/16/2010 17:24:12.65     vssphost4.exe (0x1290)                      0x17D4    SharePoint Foundation             General                           72k9    High        Failed to retrieve the list schema for feature fb18e164-124b-4da0-96d0-a6404af4996c, list template 17346; expected to find it at: "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Template\Features\Common_ListNavigation\$Resources:common,ListNavigationListName;".   

Since I try to define constants in resource files, too. I simply stored the ListTemplate.Name attribute in a resource to ensure the name does not have to be changed in different places:

<ListTemplate
    Name="$Resources:common,ListNavigationListName;"
    Type="17346"
    BaseType="0"
    OnQuickLaunch="TRUE"
    SecurityBits="11"
    Sequence="410"
    DisplayName="ListNavigationListDefinition"
    Description="My List Definition"
    Image="/_layouts/images/itgen.png"/>

Unfortunately this is not supported :-/ .

Apache Thrift 0.3.0 RC4 released

by fkollmann 6/16/2010 4:37:04 PM

The new Thrift v0.3.0 RC4 is available (for a week now). Since the team seems to take some more time to get the version ready which will most likely by the RTM, I would like to provide the Windows binaries for that build:

Thrift is a multi-platform communication framework: http://incubator.apache.org/thrift/ . The framework is also used by Apache Cassandra.

DOWNLOAD (Win32 compiler, .NET 3.5 library, .NET 2.0 library)

OUTDATED: see http://www.fkollmann.de/v2/post/Apache-Thrift-030-released.aspx

All WHS projects stopped

by fkollmann 5/7/2010 12:52:21 PM

As a consequence of changing my private project focus all currently active and already inactive WHS v1 projects have been stopped. This includes the following projects:

  • Codename “Umbrella”
  • Router Control
  • Windows Home Server on Facebook
  • Volunteer

Currently no WHS v2 versions are planned and as along as Microsoft does not include an open add-in store there won’t be any future releases.

Sorry to all who are disappointed by this and those who have been long-time companions on my WHS adventures esp. to Christopher (HSB), Alexander (HSB) and Alex (HSL). Special thanks to those who are dedicated to the WHS community and made this adventure possible: Terry (WGS) and Martin (HSB). Finally I want to thank Microsoft for providing an existing product and all the sponsors of the Windows Home Server Add-on Challenge 09.

PS: If someone is interested in continuing one of the projects, please drop me a mail.

Thrift Windows Binaries for Cassandra

by fkollmann 4/18/2010 5:56:44 PM

UPDATE: Binaries for newer versions can be found here: http://www.fkollmann.de/v2/post/Apache-Thrift-030-RC4-released.aspx .

I have been playing around with Apache Cassandra lately which is now available in v0.6. Unfortunately it’s hard to find Windows binaries for the required Apache Thrift compiler v0.2. Since I had to spend several hours to compile the compiler using cygwin, I would like to share the binaries:

Download: Thrift Compiler v0.2 for Windows

 

UPDATE: Bernhard Glück also provided binaries in the mean time.

C++ 0x features in Visual Studio

by fkollmann 4/7/2010 8:17:11 AM

Stephan T. Lavavej published a list of the C++ 0x features being implemented into Visual Studio 2008 and Visual Studio 2010. It’s a nice overview to see the current implementation status:

 

C++0x Core Language Features

Proposal

VC9

VC10

Rvalue references

N2118

No

v2

    Rvalue references v2

N2844

No

v2

    Rvalue references for *this

N2439

No

No

    Initialization of class objects by rvalues

N1610

Yes

Yes

static_assert

N1720

No

Yes

auto

N1984

No

Yes

    Multi-declarator auto

N1737

No

Yes

    Removing old auto

N2546

No

Yes

    Trailing return types

N2541

No

Yes

Lambdas

N2927

No

v1.0

decltype

N2343

No

Yes

Right angle brackets

N1757

Yes

Yes

Extern templates

N1987

Yes

Yes

nullptr

N2431

No

Yes

Strongly typed enums

N2347

Partial

Partial

Forward declared enums

N2764

Partial

Partial

Extended friend declarations

N1791

Partial

Partial

Local and unnamed types as template arguments

N2657

Yes

Yes

C++0x Core Language Features: Concurrency

     

exception_ptr

N2179

No

Yes

Thread-local storage

N2659

Partial

Partial

C++0x Core Language Features: C99

     

__func__

N2340

Partial

Partial

C99 preprocessor

N1653

Partial

Partial

long long

N1811

Yes

Yes

 

Q: http://blogs.msdn.com/vcblog/archive/2010/04/06/c-0x-core-language-features-in-vc10-the-table.aspx

Generating time-based/type 1 GUIDs

by fkollmann 3/31/2010 5:25:10 PM

Unfortunately I have been unable to find any implementation for time-based GUIDs (or “type 1” to call them correctly). Usually they are not used that often today since the random generated once are quite as good (see .NET System.Guid implementation).

However since I have been doing some testing with the Apache Cassandra “NoSQL” database I needed an implementation for .NET. This is mainly because data is sorted on write (one of the big differences to RDBS) by it’s key name AND only by it’s key name. This means if you have a distributed system writing in a database and you need a time based sorting which is globally unique, then time-based GUIDs are your choice.

I did the following implementation and ran some test cases on it. It should be fine (esp. since this is not the first time I implement them):

namespace System
{
    /// <summary>
    /// helper class to create "type 1"/time based GUIDs.
    ///
    /// see
http://de.wikipedia.org/wiki/Universally_Unique_Identifier
    /// see http://tools.ietf.org/html/rfc4122
    /// </summary>
    public static class TimeGuid
    {
        public static Guid New()
        {
            var id = new byte[16];

            // set timestamp and version
            var ts = GetNextCurrentTimestamp();

            id[0] = (byte)(ts & 0xff);
            id[1] = (byte)((ts >> 8) & 0xff);
            id[2] = (byte)((ts >> 16) & 0xff);
            id[3] = (byte)((ts >> 24) & 0xff);

            id[4] = (byte)((ts >> 32) & 0xff);
            id[5] = (byte)((ts >> 40) & 0xff);

            id[6] = (byte)((ts >> 48) & 0xff);
            id[7] = (byte)(((ts >> 56) & 0x0f) | 0x10 /* version number: 1 */);

            // set clock sequence
            var clock = _clockSequence;

            id[8] = (byte)(((clock >> 8) & 0x03) | 0x08);   // force two highest bits to be "10"
            id[9] = (byte)(clock & 0xff);

            // set mac address/node id
            var nodeId = _nodeId;

            if (nodeId.Length < 6)
                throw new NotSupportedException("node id is too short; no network card found?");

            id[10] = nodeId[0];
            id[11] = nodeId[1];
            id[12] = nodeId[2];
            id[13] = nodeId[3];
            id[14] = nodeId[4];
            id[15] = nodeId[5];

            return new Guid(id);
        }

        private static readonly short _clockSequence = 0;
        private static readonly long _timeStampBase;
        private static readonly byte[] _nodeId;
        private static long _lastTimeStamp;

        /// <summary>
        /// contains the error occurred when trying to
        /// determine the node id.
        ///
        /// consider this is a warning, there is a fallback.
        /// this field containing an error does not lead
        /// to invalid GUIDs
        /// </summary>
        public static Exception NodeIdError
        {
            get; private set;
        }

        static TimeGuid()
        {
            // create base timestamp; in .NET ticks are 100ns
            // which conforms the GUID standard
            _timeStampBase = new DateTime(1582, 10, 15, 0, 0, 0, 0, DateTimeKind.Utc).Ticks;

            // initialize current timestamp
            _lastTimeStamp = (DateTime.UtcNow.Ticks - _timeStampBase);

            // initialize clock sequence with a random value
            var rg = new Random(DateTime.Now.Millisecond);
            var rnd = Guid.NewGuid().ToByteArray();

            _clockSequence = (short)(
                (ushort)rnd[rg.Next(0, 15)] |
                ((ushort)rnd[rg.Next(0, 15)] << 0xff)
                );

            // gather node id
            _nodeId = GetNodeId();
        }

        private static long GetNextCurrentTimestamp()
        {
            var cts = (DateTime.UtcNow.Ticks - _timeStampBase);
            var lts = Interlocked.Read(ref _lastTimeStamp);

            // update last timestamp because it's outdated
            if (cts > lts)
            {
                if (Interlocked.CompareExchange(ref _lastTimeStamp, cts, lts) == lts)
                    return cts;

                // the last timestamp was already updated
                // so this means it's now up to date...
                // simply rely on its safe value!
                return Interlocked.Increment(ref _lastTimeStamp);
            }

            // the last timestamp is newer or
            // yet unchanged; rely on its safe value!
            return Interlocked.Increment(ref _lastTimeStamp);
        }

        private static byte[] GetNodeId()
        {
            try
            {
                // gather all network interfaces
                var nics = NetworkInterface.GetAllNetworkInterfaces();

                foreach (var n in nics)
                {
                    // check if a network interface has
                    // a mac address which is long enough
                    // (older devices have 6 bytes which is
                    // sufficient for GUIDs)
                    var mac = n.GetPhysicalAddress();

                    var macAddr = mac.GetAddressBytes();

                    if (macAddr.Length >= 6)
                        return macAddr;
                }
            }
            catch (Exception x)
            {
                NodeIdError = x;

                return Guid.NewGuid().ToByteArray();
            }

            // not supported or no network card found?
            NodeIdError = new Exception("no network card found");

            return Guid.NewGuid().ToByteArray();
        }
    }
}

Feel free to use the code like you want. If you find errors or good points for improvement, please let me know.

Windows Home Server on Facebook CTP1 released

by fkollmann 3/2/2010 7:55:49 PM

I am happy to announce the first sneak peak on the first Facebook integration with the Microsoft Windows Home Server out there.

Please keep in mind that this is a preview and there is still a lot of work to do but installing this version will provide valuable data on determining the direction of the project.

fbmy

UPDATE: Please note that none of the data is stored at Facebook! This is not how Facebook Apps (esp. this one) work.

HOMEPAGE, Visit on Facebook, Become a Fan

Error when retrieving WHS users

by fkollmann 2/20/2010 12:36:57 AM

Unfortunately I am currently stuck on an important feature: synchronizing users with SharePoint.

The issue is a bug in the Windows Home Server client library :-/ . But a bug has been filed so please feel free to vote for that bug since there is currently no workaround :’( . The bug applies to the German and French version.

Bug Report, Forum Post