MS.COM Operations Tools Team WebLog

Hey - What does this button do?

  • Welcome to the rest of the MSCOM Operations Team!

    Please join me in welcoming the rest of the MSCOM Operations Team to the world of blogging.  Stop by, have some coffee and leave them a comment to let them know you care. 

    -S

  • Shell in .NET, revisited

    Hi, Eric here again. A question came in to us, via email, to my post about "shelling" in .NET. I thought I would respond with a new blog entry to share with the community.

    The question was:

    From: Andreas
    Sent: Friday, July 22, 2005 7:13 AM
    Hi Eric
    I liked your piece of code that sends keystorkes too call wordpad.
    I am writing a mobile application and I
    was trying to output information from
    the application to a printer.
    I have written the information onto a
    text file in the windows CE mobile, since
    I could not find a way to output the text
    to the printer.
    I have seen your code I thought, if I
    could get wordpad to read the text
    file and output to the printer, by sending
    keystrokes.
    Please let me know if you have any ideas.
     
    Many Thanks
    Andreas
     
    Thank you for the question, Andreas. To perform what you describe, I wrote some sample code for you, included below. It:
     
    1. opens wordpad
    2. opens a file
    3. prints it
    4. closes wordpad

     

    And you can give it a command line argument to specify the location of a file to print:

     

    shell.exe C:\WINDOWS\system32\clusoc.txt

     

    If you don't give it this input argument, it has a hardcoded file path it tries to open.

    Good luck!

    - Eric

    _______

    using System;
    using System.Text;
    using System.Diagnostics;
    using System.Threading;
    using System.Windows.Forms;
    namespace shell
    {
    class shell

    {

    static void Main(string[] args)
    {
    //"shell" to open WordPad
    Process myProcess = new Process();
    myProcess.StartInfo.FileName = @"wordpad.exe";
    myProcess.StartInfo.Verb = "Open";
    myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
    myProcess.Start();
    //pause for 0.5 seconds to give the application time to open
    Thread.Sleep(500);
    //look for input argument that indicates a file path
    string PrintThisFile = string.Empty;
    if (args.Length > 0)
    PrintThisFile = args[0];
    else
    PrintThisFile = @"C:\WINDOWS\system32\perffilt.h";
    //open a file
    SendKeys.SendWait("%FO");
    SendKeys.SendWait(PrintThisFile + "~");
    //print
    Thread.Sleep(500);
    SendKeys.SendWait("%FP");
    Thread.Sleep(500);
    SendKeys.SendWait("~");
    //close the active window
    Thread.Sleep(3000);
    SendKeys.SendWait("+(%{F4})");

    }

    }

    }

     

     

  • Can't Start Debugging (F5) in VS 2005 Beta 2?

    A couple of months ago, after I had just installed the then-new Visual Studio 2005 Beta 2, I could not run any project in the IDE, as it would crash VS. Then I found a workaround using a Visual Studio community feature that I built for MSDN Forums:

    Uncheck Tools->Options->Debugger->Redirect all console output to the Quick Console Window

    You could also remove the old interop assembly:

    rmdir /s /q %windir%\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Interop\

    The new one will still be installed in 'assembly\GAC', so you should be good.

     

    This workaround came from:

    http://blogs.msdn.com/greggm/archive/2005/05/02/414111.aspx

    Which I found at:

    http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=6526

     

    You too can help yourself like I did, while in the Visual Studio 2005 IDE! Use the main menu to select “Community”, and then “Ask a Question”. This feature searches the MSDN Forums to find postings with the keywords you enter. For this feature, I developed a full component stack: SQL stored procedures, a .NET Web Service on top of that, a .NET class library on top of that, and the “Ask a Question” ASP.NET UI on top of that. Another way to search MSDN Forums is use their search UI.

    Help me, help you. :)

    - Eric

  • Like the Phoenix rising from the ashes

    As anyone who reads our little corner of the world knows, it's been a while.  Now I could make excuses that we have been busy or we lost the password or dingos ate our blog, but in truth, we simply haven't taken the time to do it.  It's funny, we all have the best of intentions.  I can't tell you how many times I've been talking with my team and someone says "I almost blogged today about....." or "I should blog about ....", but it never seems to actually happen.  I mean, we are busy and I did have to go look up the password again and ok, well the dingos were an exaggeration, but we need to make a concerted effort to poke our heads out and tell you what we've been up to.  So whether you want us to be or not, we're back.  Good to see you all again.

    -Scott

  • MOM Service Account Password Change - Update

    Some time ago I posted with respect to creating a facility for automating the MOM service account password change process. I did indeed complete the program, which can be summarized as follows:

     

    1. Expose a UI for collecting the Configuration Group and credential information, for starting the update process, and for notifying the user of progress through the various steps.

    1. Stop the MOM service on all management servers using the following .NET classes:
      - System.ServiceProcess.ServiceController
      - System.ServiceProcess.ServiceControllerStatus
    2. Shut down the DAS COM+ application using the following COM+ interface:
      - COMAdmin.COMAdminCatalog
    3. Change the DAS identity using the following COM+ interfaces:
      - COMAdmin.COMAdminCatalog
      - COMAdmin.COMAdminCatalogObject

    1. Change MOM action account, using the following .NET class to exec an updated version of SetActionAccount* that allows for providing the password as a command line parameter:
      - System.Diagnostics.Process

    1. Restart MOM (DAS is restarted automatically with it) using the following .NET classes:
      - System.ServiceProcess.ServiceController
      - System.ServiceProcess.ServiceControllerStatus 

    Along the way, however, I encountered a number of roadblocks that made this process impractical, the most significant of which was a COM+ behavior that results in the current credentials being cached beyond the application shut down. This results in having to reboot all of the management servers anyway, one of the key things I was trying to eliminate as part of this new process.

     

    In the end, the best workaround I came across is documented (though not with respect to this issue specifically) in the MOM 2005 Security Guide, the URL for which and the key section from which are appended at the end of this post. It is important to note that this workaround only works on Windows Server 2003, since only it to date supports the use of the Network Service account. Also of particular note related to the guide’s instructions are:

     

    1. Creating the SQL server login with the indicated database access results in the new database user being created for the OnePoint database, so you can skip the new database user step.

    1. By “computer name” the guide is referring to each management server in your configuration group(s). You must add a login for each management server for this to work properly.

    1. A reminder is provided in the guide, but I will add it again here as a key to avoiding possibly confusing SQL errors: Remember to add the “$” symbol to the end of the computer name for each login, i.e. domain\mgtserver1$.

    By following the steps outlined in the appended section of the security guide with the above notes in mind, you can simply automate through batch file or script the stopping and restarting of the MOM service and the use of SetActionAccount to reset the MOM action account credentials on the management servers; no reboot required. You also no longer have to worry about the DAS application, since it is running within the Network Service context.

     

    At least one other large IT group here at Microsoft beside ours is operating MOM 2005 this way, so far without any known problems.

     

    Kent

     

    * The new version of of SetActionAccount I refer to herein is available currently as a hotfix, which you can obtain by contacting Microsoft Product Support Services, or as part of MOM 2005 Service Pack 1 due out later this year.

     

     

    Microsoft Operations Manager 2005 Security Guide (Partial)

     

    Link to the complete document:

    http://www.microsoft.com/technet/prodtechnol/mom/mom2005/secguide10.mspx

     

    To use Network Service for DAS

    This process requires procedures to be done on both the MOM Database Server and then the MOM Management Server.

    Important
    You can only do this if the Management Server is running on Windows Server 2003. Windows 2000 does not support the Network Service account.

    On the MOM Database Server:

    1.      On the MOM Database Server, verify that the MSSQLSvc Service Principal Name is registered by using “setspn.exe -L <SQL Server FQDN>" at the command line, where <SQL Server FQDN> is the Fully-Qualified Domain Name of the MOM Database Server Instance.

    2.      In SQL Server Enterprise Manager, expand the OnePoint folder.

    3.      Add a new database user by right-clicking on the Users sub-node of the OnePoint database folder and selecting New Database User.

    4.      In the Database Users - New User dialog, enter the computer name in the Login name text box. Computer names follow the format domain\computername$. Do not forget the trailing “$”.

    5.      Grant this computer account user the db_owner database role membership and click OK.

    6.      Navigate to the Security folder for the SQL Server instance.

    7.      Add a new SQL Server Login by right-clicking on the Logins folder and selecting New Login.

    8.      On the General tab of the SQL Server Properties - New Login dialog, enter the computer name in the Name textbox. Computer names follow the format domain\computername$. Do not forget the trailing “$”.

    9.      On the Database Access tab, grant this computer account db_owner access to the OnePoint database by selecting the Permit checkbox next to the OnePoint database and then the db_owner checkbox below.

    10. Click OK.

    On the Management Server

    1.      On the Management Server, stop the MOM Service.

    2.      In the Component Services snap-in, expand Component Services / Computers / My Computer / COM+ Applications.

    3.      Right-click the Microsoft Operations Manager Data Access Server node and click Shut down.

    4.      After the application has stopped, open its properties.

    5.      On the Identity tab, select the System Account and the Network Service options, and then click OK.

    6.      Start the MOM Service.

    7.      After the MOM Service has started, open the MOM Administrator console and confirm that you do not see any DAS errors.

  • How about a little spin around the block?

    Sometimes we are just so focused on the task at hand, we miss some really cool stuff right under our noses.  Microsoft is such a big place, many times you don't hear about great work being done around the company by other teams.  Recently, I was asked to attend a meeting to discuss the possibility of MSCOM Operations taking over the daily operations of a project called "Virtual Labs".  Basically, Virtual Labs is just like it sounds; you can set up a virtual sandbox environment consisting of multiple virtual servers, create a virtual network between them and test drive some of our newest software online, free of charge.  If you'd like to have a look at what I'm talking about, check it out here:

    http://www.microsoft.com/technet/traincert/virtuallab/default.mspx

    There are quite a few labs already available, so have a little fun!

    That's it for now

    Scott

  • Shell in .NET!

    Maybe many of you out there in Developer Land are already aware of this, but I need to point out that you can indeed shell, sleep, and SendKeys using the new fancy C# and .NET Framework. You see, a few months ago, I needed to come up with a quick and dirty demo of a Windows application. Then I came up with the brilliant notion of shelling to it, then sending keystrokes to it to demo the app. I wondered, can you still peform this most crude form of application interoperability with the most elegant C# and .NET?

    The answer is a big YES! Check this C# code out:

    using System;
    using System.Collections.Generic;
    using System.Text;

    using System.Diagnostics;
    using System.Threading;
    using System.Windows.Forms;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                //"shell" to open WordPad
                Process myProcess = new Process();
                myProcess.StartInfo.FileName = @"wordpad.exe";
                myProcess.StartInfo.Verb = "Open";
                myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
                myProcess.Start();
                //pause for 1/2 second
                Thread.Sleep(500);
                //open the Format dialog
                SendKeys.SendWait("%OF");
                //set the font size, then ENTER
                SendKeys.SendWait("{TAB}{TAB}48~");
                //type some text
                SendKeys.SendWait("Hello world");
            }
        }
    }

    The above code is a console EXE program that brings up WordPad, then types a big "Hello World", with a 0.5 second sleep in between to give WordPad time to open. I love this code -- it is SO old school. It warms my heart that you can still stoop to this level. I hope you enjoy it as much as I.

    For a list of all of the SendKeys codes, see the following page in MSDN online:

    http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWindowsFormsSendKeysClassTopic.asp

    Happy coding!

    - Eric

  • What's Wrong With This Code (T-SQL Edition)

    This code (actually, code very much like it) made it through development and test (in a different team; we never make mistakes,) and worked beautifully.  In production, however, it was an utter failure.  It isn't difficult to spot the problem; can you?

    ----------------------------------------------


    INSERT INTO BigFatTable (Name, Description, Time)
    VALUES (@Name, @Description, @Time)
    SELECT @Output = SCOPE_IDENTITY()
    FROM BigFatTable

    ----------------------------------------------


    //
    //   Llywarch Moel
    //      (aka Number 5)
    //
  • Woe to ATI

    For many years I have been pretty heavily involved in the gaming industry.  Through scores of beta tests, to assisting in the design of scalable systems for third generation MMORPGs to writing reviews and conducting interviews I’ve been in, out and around the industry since it became an industry.

     

    Of course game graphics and system hardware have come a long way in a ridiculously short amount of time.  Who remembers when 3dfx graphics cards were all the rage?

     

    In recent years the showdown on the graphics front is between nVidia and ATI.  Now nVidia has held the lead for quite some time and the weight of it has made them stagger at times.  ATI, ever the stalwart competitor has put up a good fight and come up with some very good products over the years.

     

    Being a massive nerd, I love to build my own game systems.  During my last build I decided to take a shot on the latest and greatest ATI card.  I had previously only purchased nVidia products as I had felt they were marginally better in performance but mostly because I knew that game developers used them in their development machines.  But the RADEON 9800 Pro 256 was my choice at the time. 

     

    A choice I have regretted every single day.

     

    Since the day I booted my newly assembled behemoth containing all of the latest and greatest gaming hardware (for that millisecond) the 3D gaming quality on this Sapphire OEM has been deplorable.  Some games, the games that are more 2D based than 3D based had almost no problems, but every game that renders 3D objects has quality issues.  Every single game.  Now, simple model and texture games such as Zoo Tycoon 2 have the minor irritation of the occasional flashing texture.  Easy to overlook and ignore and in all likelihood ATI will release a driver update to relieve this issue even more.

     

    But games with heavy 3D, like EverQuest 2, World of Warcraft, Doom 3, and Half-Life 2 have significant problems with bad textures, broken models, running text, ad nauseam.  And forget about Battlefield Vietnam, that’s just texture stew.

     

    Sapphire tells me to talk to ATI, of course.  ATI has been stringing me along with “that should be fixed in driver update X” messages for months.  The store I bought it from wouldn’t take it back after the first 30 days (and who can blame them?  After 30 days a used graphics card is scrap silicon to a retailer).

     

    I had taken the last 6 weeks off of my harassment campaign for support and decided to try it once again.  Just to see if I got any different kind of result.  Um, yeah.

     

    In all the time I’ve been trying to resolve this problem with ATI, not one single time has anyone asked for a screenshot of the problem despite my offering to provide them every time.  In all this time not once was there ever a mention of simply replacing my defective card with a new one.  I paid almost $500 for it and you can now pick that same card up for about $250.  And I know it is simply my card that is defective.  I’ve borrowed the exact same card from a friend who bought his from the same place I did at the same time I did and his works just fine in my machine.  I’ve also tried an nVidia based card.  No problems.  Clearly I have a defective unit and you would think ATI could afford to replace it.

     

    The last email I received from ATI suggested that I adjust my bios settings with things such as “Set your AGP support from 8X to 2X”, among others.

     

    I made sure to reply: “Thank you for supporting nVidia.”

     

    Will

  • Lockdown

    Ah, the holidays. 

    For people in most operations organizations, there is a collective sigh of relief around this time of year.  Not only are many of the people who are responsible for releasing changes out into the production environment on vacation (or getting ready for vacation), but the holidays are the joyful time of year that dances in the dreams of every operations person...the time of Data Center lockdowns.  If vacations are not enough to sway the throng of projects coming down the pipe with the frequency of a firehose, Saint Nick and his elves (read data center staff) give us all the gift of peace for 3 weeks.  This is not to say that code releases don't still happen, they do to be sure.  However, with no new server deployments, server rebuilds, or really data center staff available, we in operations get a nice reprieve.  Interestingly, many ops folks end up working through the holidays just because it's quiet!  So to all the data centers who require holiday lockdowns, from all of us to all of you, a collective thank you!   

    Scott

  • Easing the Digital Photo File Storage Crisis

    After owning a digtial camera for a year and a half, I now have about 6000 photo files, which have swamped my old home computer's 16GB harddisk. So on the day after Thanksgiving, popular for shopping, I considered going to Fry's to buy an external harddisk. They had some great discounts going on, and I had never made the pilgrimage to this haven of geekdom. Then, I thought better of driving the 15 miles and fighting the crowds. I stayed home and took advantage of their sales online, which led to the purchase of the 160GB external harddisk for $60, after rebate.

    While I waited for my order to arrive, I decided to write a utility program to better organize my 6000 photos. It was taking forever to open my big photo file folder! My new program copies all of the files found within one folder tree to a new folder tree, which has the files broken out by the date each picture was taken. A distinct folder is created for each day a picture was taken. Now it is easy to open the root folder, and find all the pictures from Christmas 2003, for example. With a little more polish, this utility could be ready for public consumption.

    Geek out,

    Eric

  • Unheard of temperatures

    I was recently working on a thermometer control and decided to write a temperature class to go along with it.  What I found interesting is that there are temperature systems that I had never even heard of let alone used (namely Reaumer and Rankine).  I'm from Canada and I've heard of some pretty nasty temperatures, but these were still a suprise to me. :-)  Anyway I wrote the class in C# and thought others might find some use in it.   Here it is:

     

    using System;

    namespace ThermometerDemo
    {
        /// <summary>
        /// Summary description for Temperature.
        /// </summary>
        public class Temperature
        {
            public enum SystemOfMeasure { Fahrenheit = 0, Celsius, Kelvin, RanKine, Reaumer };

            private SystemOfMeasure _systemOfMeasure;
            public SystemOfMeasure Scale
            {
                get { return _systemOfMeasure; }
                set { _systemOfMeasure = value; }
            }

            private double _temperatureKelvin;
            public double Value
            {
                get { return Temperature.Convert( _temperatureKelvin, SystemOfMeasure.Kelvin, _systemOfMeasure ); }
                set { this._temperatureKelvin = Temperature.Convert( value, _systemOfMeasure , SystemOfMeasure.Kelvin ); }
            }

            public double AbsoluteZero
            {
                get { return Temperature.Convert( 0F, SystemOfMeasure.Kelvin, _systemOfMeasure ); }
            }


            #region Construction

            public Temperature() : this( SystemOfMeasure.Kelvin, 298.15F )
            {
                // SI temperature at standard state in Kelvin.
            }

            public Temperature( SystemOfMeasure systemOfMeasure ) : this( systemOfMeasure, 298.15F )
            {
                // SI temperature at standard state.
            }

            public Temperature( double temperature ) : this( SystemOfMeasure.Kelvin, temperature )
            {
            }

            public Temperature( SystemOfMeasure systemOfMeasure, double temperature )
            {
                _systemOfMeasure = systemOfMeasure;
                Value = temperature;
            }

            #endregion Construction


            # region Public Methods

            public static double Convert( double temperature, SystemOfMeasure originSystem, SystemOfMeasure targetSystem )
            {
                // Convert to Kelvin.
                double temperatureKelvin;
                switch( originSystem )
                {
                    case SystemOfMeasure.Fahrenheit:
                        temperatureKelvin = ( 5F / 9F ) * ( temperature - 32 ) + 273.15F;
                        break;

                    case SystemOfMeasure.Celsius:
                        temperatureKelvin = temperature + 273.15F;
                        break;

                    case SystemOfMeasure.Kelvin:
                        temperatureKelvin = temperature;
                        break;

                    case SystemOfMeasure.Reaumer:
                        temperatureKelvin = ( 5F / 9F ) * temperature + 273.15F;
                        break;

                    case SystemOfMeasure.RanKine:
                        temperatureKelvin = temperature / 1.8F;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException( "originSystem", originSystem, "Unsupported origin system of measure");
                }

                // Convert to the new system.
                double resultTemperature;
                switch( targetSystem )
                {
                    case SystemOfMeasure.Fahrenheit:
                        resultTemperature = 32F + ( 1.8F ) * ( temperatureKelvin - 273.15F );
                        break;

                    case SystemOfMeasure.Celsius:
                        resultTemperature = temperatureKelvin - 273.15F;
                        break;

                    case SystemOfMeasure.Kelvin:
                        resultTemperature = temperatureKelvin;
                        break;

                    case SystemOfMeasure.Reaumer:
                        resultTemperature = ( 1.8F ) * ( temperatureKelvin - 273.15F );
                        break;

                    case SystemOfMeasure.RanKine:
                        resultTemperature = temperatureKelvin * 1.8F;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException( "originSystem", originSystem, "Unsupported target system of measure");
                }

                return resultTemperature;
            }

            public static string GetUnitAbbreviation( SystemOfMeasure systemOfMeasure )
            {
                switch( systemOfMeasure )
                {
                    case SystemOfMeasure.Fahrenheit:
                        return "°F";

                    case SystemOfMeasure.Celsius:
                        return "°C";

                    case SystemOfMeasure.Kelvin:
                        return "K";

                    case SystemOfMeasure.Reaumer:
                        return "°Re";

                    case SystemOfMeasure.RanKine:
                        return "°Ra";

                    default:
                        throw new ArgumentOutOfRangeException( "systemOfMeasure", systemOfMeasure, "Unsupported system of measure");
                }
            }

            #endregion Public Methods
        }
    }

    eHowitzer

     

  • Funny Business

    The entertainment industry is a funny business.  It is completely dependant on the random whims of consumers.  That is not to say that the success of a product is unpredictable, simply that there are a great many factors involved in design, development and distribution of an entertainment property that getting them all together is a fluid venture at best.

     

    As I’m sure we all know, Halo 2 dropped recently to great fanfare.  This follow up to the perennial Xbox title was highly anticipated and accompanied with some killer trailers and excellent television commercials.  The media was whipped into a savage frenzy that culminated in a $125 million dollar opening day bombshell.

     

    Numbers like that are simply unprecedented.  Nothing has ever come close to matching a single day total like that of Halo 2.  Even such powerhouse properties as the Spider-Man movie franchise pales in comparison.  Spider-Man 2 bowed in with an opening weekend, a long 4th of July weekend I might add, with $115 million.  But let’s compare something a little closer, digital animated feature films.  Shrek 2 bowed in with an opening weekend of $108 million.  Finding Nemo racked up $70 million in its debut weekend.

     

    By those comparisons, Halo 2 devastated the entertainment industry.  However, if we take a step back and view the entire domain of digital entertainment, a different picture begins to take shape.  Shrek 2 piled up $436 million in US domestic box office sales during its 14 week theatrical run and Finding Nemo scored $339 million for its 29 week run.  Remember, that is the US box office sales.

     

    Some estimates suggest that approximately 15 million Xbox units have been sold worldwide.  If one copy of Halo 2 were sold for every Xbox at $50 per sale, then Halo 2 would scratch up $750 million in worldwide sales.  As much as I would love to see that come to fruition, I just can't see it.  In fact, I can’t see sales of Halo 2 topping $400 million, but it is possible.

     

    Now look at this picture again, Shrek 2 scored $436 million in US box office sales.  Halo 2 _could_ reach $750 million world wide.

     

    Take another step back and the fog begins to clear.  Worldwide box office figures for Shrek 2 and Nemo top out at $849 and $865 million respectively.  And we haven’t even begun to touch DVD and VHS sales or rentals yet.

     

    Sure the Halo 2 release was a massive success, but let’s not consider it an earth shattering event just yet.

     

    Which brings me to another issue.  What the hell is wrong with Disney?  Have they become so bloated that they have forgotten how to make a good animated movie?

     

    Look at the charts and it’s clear to see that the future of Disney animation is Pixar.  At least, one would think so.  Since 1989 Disney has released 9 traditional animation movies and 6 digital animation movies in conjunction with Pixar.  The most lackluster of all the Pixar movies, A Bug’s Life (1998), currently sits at #84 in the all time box office charts with $357 million.  At $357 million, A Bug’s Life roasts all of the traditional animation releases except for Tarzan (1999, #51 @ $435), Aladdin (1992, #35 @ $501) and The Lion King (1992, #15 @ $784).

     

    And, with the exception of A Bug’s Life, each successive Pixar movie has out grossed it’s predecessor.  With an opening weekend take of $143 million, The Incredibles looks to continue this trend (remember, Finding Nemo took in $70 million in its opening bow in 2003).

     

    One would think that cultivating a relationship with Pixar would be a top priority at Disney, but instead they have done nothing but breed animosity and distrust.  To the point where Pixar has decided to take their toys and play in someone else’s sandbox.  Cars, the next feature from Pixar (slated for 2005) will be the final movie in the current contract between Disney and Pixar.  Rather than try and smooth the ruffled feathers and extend that contract, Disney has apparently decided to spin up their own digital animation division (how long did it take to make this decision?  6 years?  Right on time guys.) and crank out…Toy Story 3.  Toy Story 2 is where the bad blood began between these companies to begin with.

     

    The question has been raised as to whether Pixar can survive without Disney.  In my opinion this isn’t even a question.  Even if Pixar did not want to handle their own financing, publicity and distribution business (which they certain could) there are many powerhouse studios who are just waiting to swoop in and steal this money maker.  Fox Studios has struggled with their animation division for years and finally landed a winner with Ice Age.  They’ve got the juice to take on Pixar.  Dreamworks has their own very successful animation studio (coincidentally Disney is building their digital division in Glendale California, not far from the Dreamworks studio) however, Dreamworks has shown a penchant for being opportunistic and could certainly handle bringing Pixar into their stable.  Sony, Paramount and perhaps half a dozen others could all be interested in handling the load.

     

    At this rate Disney animation will die a slow and agonizing Lilo & Stitch 6 death.

     

    Will

  • New Guy Likes Chess

    Hello, there. I'm Eric, a brand new addition to the Microsoft.com Operations Tools Team. As a part of beaming into the team, I thought I would try the team weblog. For the subject of my first post, I will keep it relatively light: playing chess. I have been enjoying playing occasional friendly games of chess for many years, and enjoy it in many forms. I am no Grandmaster, but I have some basic battle skills, as some of my new teammates are finding out firsthand.  >:]

    It is great to play at home on my nice big wooden board with the solid, heavy, wooden pieces which yield a satisfying thud when you place them, adding emphasis to your decisions. But I rarely get to play on that board at home.

    More convenient, is playing chess on the Web. I have played games at Yahoo and MSN. These sites are cool -- clocks, rated games, play people in real-time all around the world, chat with them during the game, 24x7. Another novel way to play is via MSN Instant Messenger. You can challenge your IM contacts to chess, checkers, tic tac toe and more.

    However, all of these forms of chess involve waiting -- waiting for your opponent to move -- which can be a drag. When using a clock, your wait is your gain. Without a clock, once you have your next move figured out, based on the move you just know they will do, you are left to: trash talk, small talk, day dream, think about work. Not the optimum use of your time  :)

    Which brings me to a more time-efficient way to go: correspondence chess. This style of chess has been practiced for eons. A primitive form is sending notations describing moves via snail mail, while you keep a board at home/work set up with the current state of the game. The beauty of correspondence chess is you can take all the time you need, while your opponent pursues other interests -- no waiting. The downside is that paper mail involves postage, envelopes, and thinking about postal pickup times.

    Fortunately, computing has improved correspondence chess. I played the first form of electronic correspondence chess a few years ago, using email and custom Exchange chess forms, built with Visual Basic. Moves would arrive via email. You opened the email, and the board would render. Make a move, send it back. Take all the time you want. What fun! And you could replay entire current games, and past games, stepping through each move, one by one. The bad news is that this custom Exchange form seems to be extinct now, when running newer versions of Exchange and Outlook.

    So, the other day, I wondered if somebody had yet created webpage-based correspondence chess. The answer is yes, and there are many choices! You make moves on a webpage, click a button, and then your opponent gets an email notification with a link back to the game board. You install nothing. Perfect!

    Some require a substantial registration. I have tried two that don't require registration:  eChess.org, PostcardChess.com. But my favorite so far is SchemingMind.com. It requires a modest registration, but it is worth it. Unlike those other two, SchemingMind shows the game history, offers replaying of each move, stores your past games for later review, and might enforce more rules. eChess.org states clearly that rule enforcement is up to the players.

    I understand that there is another way to play where you install a client desktop application and configure it to connect to some chess server. But this has always seemed like too much trouble to me.

    There you have it, enough information to get you started burning all of your free time playing chess -- I mean keeping your mental faculties extra sharp via logical chess problem solving.

    Bring it on,
    - Eric
  • Event Debouncing

    I have recently encountered a situation where my code was receiving objects sent, via a scoping event, from code on another thread.  These "scope" objects require my code to change state to reflect the object received.  This resulted in my code receiving scoping events at inopportune times (such as in the middle of working on the previous scope change).  I needed a way to "de-bounce" the scope changes in order to ignore them while I was updating, and also check when I was finished updating to see what scope changes had occurred while I was processing.  Here is a simple solution that I put together to help solve the problem.  The first code block shows my usage of the class, and the second is the class itself.  I hope you find it interesting (and maybe useful).

        // Code Block #1: Usage
        private ScopeTracker _scopeTracker = new ScopeTracker( ScopeTracker.TrackingStyle.DiscardAllButLast );

        public override void OnScopeChanged(object scope)
        {
            _scopeTracker.TrackChange( scope );
            If( !updatingState )
            {
                if( _scopeTracker.IsNewScopeChange() )
                {
                    this.UpdateState( _scopeTracker.ConsumeNextScopeChange() );
                 }
            }
        }

        private void UpdateState ( object o )
        {
            if( updatingState )
            {
                return;
            }

            updatingState = true;

            // do work on another thread (possibly)…

            updatingState = false;

            if( _scopeTracker.IsNewScopeChange() )
            {
                this.UpdateState( _scopeTracker.ConsumeNextScopeChange() );
            }
        }


        // Code Block #2: Class definition.
        public class ScopeTracker
        {
            public enum TrackingStyle { QueueAll, DiscardAllButLast };
            public object LastScopeChange
            {
                get
                {
                    return _lastScopeChange;
                }
            }

            private TrackingStyle _trackingStyle;
            private Queue _trackedScopeChanges = new Queue();
            private object _lastScopeChange = null;

            public ScopeTracker( TrackingStyle TrackingStyle )
            {
                _trackingStyle = TrackingStyle;
            }

            /// <summary>
            /// Returns true if the change is tracked, else returns false.
            /// </summary>
            /// <param name="ScopeObject"></param>
            /// <returns></returns>
            public bool TrackChange( object ScopeObject )
            {
                bool bTracked = false;

                // If we are only tracking the last scope change, then throw away any previous
                //    scope changes we are tracking.
                if( _trackingStyle == TrackingStyle.DiscardAllButLast )
                {
                    _trackedScopeChanges.Clear();
                }

                // Only track changes if they are changes.
                if( 1 > _trackedScopeChanges.Count )
                {
                    // Since we don't have any changes in the queue check to see if this new
                    //    one is different than our last one.
                    if( _lastScopeChange != ScopeObject )
                    {
                        _trackedScopeChanges.Enqueue( ScopeObject );
                        bTracked = true;
                    }
                }
                else
                {
                    // We have changes in the queue, so see if this new one is the same as the last
                    //     change we put in the queue.
                    if( ScopeObject != _trackedScopeChanges.Peek() )
                    {
                        _trackedScopeChanges.Enqueue( ScopeObject );
                        bTracked = true;
                    }
                }

                return bTracked;
            }

            public object ConsumeNextScopeChange()
            {
                if( 1 > _trackedScopeChanges.Count )
                {
                    return null;
                }

                _lastScopeChange = _trackedScopeChanges.Dequeue();
                return _lastScopeChange;
            }

            public bool IsNewScopeChange()
            {
                if( 1 > _trackedScopeChanges.Count )
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }

            public object SyncToValidScope()
            {
                if( this.IsNewScopeChange() )
                {
                    return this.ConsumeNextScopeChange();
                }
                else
                {
                    if( null != _lastScopeChange )
                    {
                        return _lastScopeChange;
                    }
                    else
                    {
                        return null;
                    }
                }
            }
        }

More Posts Next page »

This Blog

Syndication

Tags

No tags have been created or used yet.

News

All opinions posted here are those of the author(s) and are in no way intended to represent the opinions of our employer. This is provided "AS IS" with no warranties, and confers no rights. Use of included code samples are subject to the terms specified in the Terms of Use.

©2005 Microsoft Corporation. All rights reserved. Terms of Use |Trademarks |Privacy Statement
Microsoft