Archives

Archives / 2008 / October
  • Installing Visual Studio Extensions for Windows SharePoint Services on Windows XP

    Yes, it is possible!

    First, download Visual Studio 2005 Extensions 1.1 for WSS 3.0 from http://www.microsoft.com/downloads/details.aspx?FamilyID=3e1dcccd-1cca-433a-bb4d-97b96bf7ab63&displaylang=en. You can also download version 1.2 for Visual Studio 2008 from http://www.microsoft.com/downloads/details.aspx?FamilyID=7bf65b28-06e2-4e87-9bad-086e32185e68&displaylang=en. Now, if you try to install this on an OS other than Windows Server 2003 or 2008, it won't install. What you have to do is add a string value to the registry:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0

    "Sharepoint" (String value) ="Installed"

    And that's it! Both installers will do their job without complaints.

    BTW, I learned this from Martin Vollmer's Blog: http://blogs.msdn.com/martinv/archive/2008/10/31/how-to-install-visual-studio-extensions-for-windows-sharepoint-services-1-2-on-vista-or-windows-xp-vsewss-exe.aspx. Thanks, Martin!

    Read more...

  • Application Domains

    There may be times when you need create additional application domains. What for? I can think of at least two reasons:

    • There is need to limit what a class can do, for example, file I/O accesses, memory usage limits, startup directory, assembly references, and so on;
    • Dynamic code generation (types and assemblies), by using System.CodeDom or System.Reflection.Emit, will stay in the memory of the current domain for ever, which may lead to memory leaks.

    An application domain (an instance of the System.AppDomain class) can be unloaded from memory, while types (System.Type) and assemblies (System.Assembly) cannot. For example, if you call:

    AppDomain.Unload(AppDomain.CurrentDomain);

    your program will terminate silently as the current (and, by default, only) domain of the process was unloaded.

    Back to our problem; our goal is to:

    1. Create a new application domain;
    2. Applying it any restrictions we want;
    3. Creating an instance of our target class in it;
    4. Invoking the target method of the target class in it;
    5. Unloading the application domain when it is no longer needed.

    Your code may look like this:

    [Serializable]

    class ClassThatRunsOnAnotherAppDomain: MarshalByRefObject

    {

        public void DoSomething()

        {

            String fn = AppDomain.CurrentDomain.FriendlyName;

            //fn contains UnloadableDomain

        }

    }

     

    public class Program

    {

        public static void Main(String [] e)

        {

            AppDomainSetup setup = new AppDomainSetup();

            //the Assembly.CodeBase property is a URI, so we must remove the scheme part

            setup.ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Replace("file:\\", String.Empty);

            AppDomain domain = AppDomain.CreateDomain("UnloadableDomain", null, setup);         ClassThatRunsOnAnotherAppDomain cls = domain.CreateInstance(Assembly.GetExecutingAssembly().FullName, typeof(ClassThatRunsOnAnotherAppDomain).FullName).Unwrap() as ClassThatRunsOnAnotherAppDomain;

            CrossAppDomainDelegate del = new CrossAppDomainDelegate(cls.DoSomething);

            String fn = AppDomain.CurrentDomain.FriendlyName;

            //fn contains something like 76837b64-1-128695018546718750

            domain.DoCallBack(del);

            //do something here before calling AppDomain.Unload - be carefull, if the DoSomething method has not yet terminated, it will be terminated abruptly but silently

            AppDomain.Unload(domain);

        }

    }

    If you want to synchronize the call to AppDomain.Unload with the termination of the DoSomething method, the best thing is to use an event; include the following code before the call to domain.DoCallBack(del):

    EventWaitHandle evt = null;

    try

    {

        //try to open an existing named event    evt =
    EventWaitHandle.OpenExisting("EventName");

    }

    catch (WaitHandleCannotBeOpenedException)

    {

        //named event does not exist, so create one

        evt = new EventWaitHandle(false, EventResetMode.AutoReset, "EventName");

    }

    and just before unloading the domain:

    evt.WaitOne();

    In the DoSomething method, signal termination:

    evt.Set();

    Read more...

  • The using Statement

    Updated: there is no inner try...catch in the outer finally block, readers who mentioned it are right! Thanks!

    Together with the lock statement, the using keyword is also relatively mysterious:

    using (IDisposable instance = ...)

    {

        //do something

    }

     

    is equal to: 

     

    IDisposable instance = ...;

    try

    {

        //do something

    }

    finally

    {

        if (instance != null)

        {

            instance.Dispose();

        }

    }

    Read more...

  • The lock Statement

    Experienced multithreading developers may have wondered what is the relation between the lock keyword and the System.Threading.Monitor class. Well, as it happens, they are exactly the same:

     

    lock (instance)

    {

        //do something

    }

     

    is exactly equal to:

     

    try

    {

        Monitor.Enter(instance);

    }

    finally

    {

        Monitor.Exit(instance);

    }

     

    Bear in mind that the finally clause is necessary so that the lock is released.

    Make sure you never lock on the object instance, but on an inner field instead, because the .NET Framework may also need to lock the instance, which may lead to a deadlock.

    Read more...

  • NHibernate 2.0.1 and NHibernate Validator 1.0.0 Launched

     NHibernate 2.0.1 was launched. You can get it at http://sourceforge.net/project/showfiles.php?group_id=73818&package_id=73969&release_id=629506.

    Additionally, NHibernate Validator 1.0.0 was also launched, and the download location is http://sourceforge.net/project/showfiles.php?group_id=216446&package_id=275108. Read all about it on the NHForge site. I'm interested in knowing how does it compare to the Enterprise Library Validation Application Block, which is what I've been using in my recent projects.

     

    Read more...