2012-02-16

BSOD on Lenovo ThinkPad W510 w/Intel SSD

I have a Lenovo ThinkPad W510 with intel SSD (about 75 Gigs). I’ve been having a lot of bluescreens, but now I think I’ve solved the problem by a firmware update on my SSD.

My first problem was that I do not have an alternate boot device: no floppy and no CD/DVD drive, so I had to make a bootable USB Flash Drive, and boot from it. Here’s how to do that: http://arstechnica.com/business/news/2009/12/-the-usb-flash-drive.ars, or even like this: http://johnpapa.net/BootFromUSB. Come to think of it, it’s always nice to have an alternative boot device available, as a sort of Windows rescue disk.

So after that I downloaded the Intel Firmware Update Tool: http://downloadcenter.intel.com/Detail_Desc.aspx?agr=Y&DwnldID=18363.

Copy the tool to the flash drive.

Boot from flash drive, then run the tool. Booting from the flash drive might require you to enter into the BIOS setup to change the boot sequence so that an attempt to boot from the USB device is made.

No BSOD (Blue Screen of Death) for 2 weeks now, and I used to have them at least once a day, one day I had one every hour or so.

Here’s an alternative path with full description:
http://communities.intel.com/thread/8906

Hope this helps someone.

2012-01-03

Debugging Windows BSOD (Windows 7)

Here are some steps to take if your Windows PC regularly crashes, showing the infamous Blue Screen of Death (BSOD):

  1. Download and install the “Debugging Tools for Windows” x64 or x86 depending on your hardware architecture.
  2. Set path to symbol files.
  3. Start WinDbg, and select “Open Crash Dump” from the File menu.
  4. Select the latest crash dump file.
  5. Read the output, at the bottom you will find the likely cause of the crash.

This is the full story: http://www.networkworld.com/supp/2011/041811-windows-7-crashes.html?page=1

2011-12-01

Synchronizing SQL Server Stored Procedures between databases

In my earlier post Compare Stored Procedures in 2 SQL Server databases, I wrote about how it is possible to select from INFORMATION_SCHEMA to compare stored procedures.

The issue I am dealing with here is that during the development af a new system, the database stored procedures are likely to change between each release to a server (test, staging or production). You have made all the changes in your development database, and you just need to copy the changes to the other database. My old way to do this was to script each SP whenever it changed and link a section in the delivery slip to the script, which was quite tedious.

What I ended up with using in one of my current projects is the following steps:

  1. Using SQL Server Management Studio, script all procedures from the source database as ALTER to the clipboard.
  2. Connect a new query window to the target database and paste the script.
  3. Run the script.

    It will fail for all the SPs that you have added to the source database, which are missing in the target database, but also it will update all existing stored procedures to the latest version.

  4. Replace all “ALTER PROC” with “CREATE PROC” in the script and run it again.

    It will fail for all existing SPs in the target database, but more importantly, it will create all the SPs from the source database that are missing in the target database.

  5. And Bob’s your uncle!

This, of course, should be easy to automate. Maybe I’ll come back with an application that does it in an upcoming post.

The routine above works for functions as well, and should/could also work with views, and maybe also tables.

2011-09-27

Mailinator.com

If you ever need to test a system with lots of different unique email addresses, then Mailinator may be just the thing you need.

Whenever you send an email to some random name @mailinator.com, you can go into the mailinator web site, type the email address (without the “@mailinator.com” part), and log on to check the mail. You don’t even need to register.

Some scenarios may be:

  • Register users with unique emails
  • Test confirmation mail functionality
  • Test forgotten password functionality

2011-09-15

Adding a ToXmlString() extension method to all objects so that they may be viewed as Xml when debugging

Working with soap Request and Response objects I have found that it is a nice thing to be able to check the request, and copy it into SoapUI to test what really is going on. So my first thought was to create an extension method and put it on all my request objects, but it takes some work, so I went for the lazy solution: add extension method on System.Object. Now this may not work on all objects, I think they need to be serializable at least, but it seems to work on my request objects. So here’s my code, just use it with caution, as it may have side effects:

using System;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

public static class ExtensionMethods
{
    public static string ToXmlString(this System.Object obj) { return serializeObject(obj); }
   
    private static string serializeObject(object obj)
    {
        XmlSerializer xs = new XmlSerializer(obj.GetType());
        StringWriter sw = new StringWriter();
        XmlTextWriter w = new XmlTextWriter(sw);
        w.Formatting = Formatting.Indented;
        w.Indentation = 3;

        xs.Serialize(w, obj);
        w.Flush();
        w.Close();

        return sw.ToString();
    }
}

 

2011-09-07

Compare Stored Procedures in 2 SQL Server databases

Using the following script it is possible to get an idea if the stored procedures in two databases are equal.

SELECT A.ROUTINE_NAME, A.ROUTINE_DEFINITION, B.ROUTINE_DEFINITION
FROM sourcedatabase.INFORMATION_SCHEMA.ROUTINES A
LEFT JOIN targetdatabase.INFORMATION_SCHEMA.ROUTINES B ON A.SPECIFIC_NAME = B.SPECIFIC_NAME
WHERE RTRIM(LTRIM(SUBSTRING(A.ROUTINE_DEFINITION,CHARINDEX('CREATE',A.ROUTINE_DEFINITION),999))) <> RTRIM(LTRIM((SUBSTRING(B.ROUTINE_DEFINITION,CHARINDEX('CREATE',B.ROUTINE_DEFINITION,0),999))))
ORDER BY ROUTINE_NAME

Even if the routines have the same functionality, they may have some slight differences, like spaces in front of the CREATE PROCEDURE statement and also trailing spaces at the bottom. I have tried to remedy this by trimming and also comparing substrings where initial spaces have been removed. Still room for more improvement, I’m sure, but just a small idea.

2011-05-23

IIS AppPool and ApplicationPoolIdentity

When you create a new web site in IIS 7.5, an Application Pool is created by default with the same name as the web site.

After Windows Server 2008 SP2, you may select “ApplicationPoolIdentity” as the account to run the app pool with.

ApplicationPoolIdentity is an account on the local machine with the same name as the Application Pool.

If you want to give your web application access to files or other resources outside your web root directory, perform these steps:

  • Right Click the file or folder (or registry key?) you want to give access to, and select Properties from the dropdown.
  • Go to the Security Tab, click the “Edit…” button.
  • Click “Add…”.
  • Click “Locations…” and select the local machine.
  • Under “Enter the object names to select…”, type IIS AppPool\<ApplicationPoolIdentity>, where <ApplicationPoolIdentity> is the same as the Application Pool name.
  • Give rights as needed, click OK as many times as it takes, etc.

I think this should be enough to get you started.

Source: http://learn.iis.net/page.aspx/624/application-pool-identities/

2011-04-15

Setting up Oracle Instantclient Basic

I have been working on setting up an oracle instant client basic connection, using the following article:

http://www.dbatoolz.com/t/installing-oracle-instantclient-basic-and-instantclient-sqlplus-on-win32.html

Ran into one problem which took me a little time to figure out. The article says to add an environment variable as a “User Variable”. Since I am running a web site that has an application pool running on the NETWORK SERVICE account, and it is not possible to log on using that account and set the User Variables, they will not be available to my web app.

The solution is to add all variables as System Variables (using the lower part of the Environment variables window).

Just to be safe, I also added a variable for “ORA_HOME” with the same value as the TNS_ADMIN environment variable, namely the path to the instantclient (in my case “instantclient_11_2”) folder.

2011-04-11

System.Security.Cryptography.CryptographicException: Key not valid for use in specified state

I got this message after I created a new user profile on my virtual machine (VMWare), and tried to compile my ORM project (using Telerik OpenAccess ORM). The error was wrapped as: OpenAccess Error: Key not valid for use in specified state.

This is not a problem for OpenAccess only though. I’ve seen that it also may be a problem for other applications, like SQL Server Reporting Services.

The solution:

  1. Go into the folder (Windows XP) at:
    <drive>:\Documents and Settings\<your windows user account name>\Application Data\Microsoft\Crypto\DSS\<your machine SID>\
  2. Delete the file there. It should have some cryptic name (like a GUID).
  3. Restart IIS (IISRESET).
  4. Recompile. It worked for me.

 

References:

2011-03-29

My experiences from installing EPiServer CMS 5 on Windows XP

Installing EPiServer CMS 5 on a Windows XP developer VM turned out to be a bit of hazzle, maybe because XP is not a “supported” OS any more?

Ok, so first installed the EPiServer CMS5 5.2 R2 application files to the default location. No problem so far.

Since I am working on an existing web site, I created a folder on disk and got latest version from TFS.

I then copied the EPiServer binaries into my bin-folder (XCOPY-deployment), and attempted to browse the website. I got this message:

Could not load type 'EPiServer.UI.WebControls.ControlAdapters.HtmlHeadAdapter'.

This error message originated from the App_Browsers / AdapterMappings.browser file.

I then went into my web.config file and verified that my VPP paths were mapped correctly to files in the Program Files\EPiServer\CMS\5.2.375.236\Application folder.

So my next thought was to open the edit/admin mode. Alas, it looked all messed up, missing both styles and graphics.

This gave me my next clue, because in EPiServer 4.x you had to remap the 404 http error status to /utils/NotFound.aspx to make the admin/edit modes look as they should, as I described in my previous posting: http://stgaup.blogspot.com/2009/10/styles-missing-in-episerver-editadmin.html.

That trick does not seem to work on CMS 5 (only works on EPiServer 4.x). Now in stead you need to do something a bit different:

  1. Open the “Properties” for your web site in the IIS manager.
  2. On the “Home Directory” tab, click the “Configuration…” button.
  3. On the “Mappings” tab, click the “Add” button.
  4. Click the “Browse” button next to the “Executable” text box.
  5. Navigate to the Windows/Microsoft.NET/Framework/v2.0.50727 folder.
  6. Select “Dynamic Link Libraries” in the “Files of type” dropdown.
  7. Select the “aspnet_isapi.dll” file, and click the “Open” button.
  8. Fill in the “Extension” as “.*” (dot-star).
  9. TRICK: There’s a bug in Windows XP that has never been fixed, that causes the “OK” button to remain disabled. Click in the “Executable” text box again and then voila, the “OK” button is enabled.
  10. Click OK as many times as it takes to get back to the “Internet Information Services” application.

Now try to reload your admin/edit mode. It should work.

Some good links:

2011-03-04

Themed CheckBox check mark

Themes for ASP.NET applications came probably in 2005 with .NET 2.0, so it’s been around for a while.

I am creating different themes to adapt my web appliction to different clients.

So the problem I came across with the ASP CheckBox control is that setting the size of the control does not change the size of the check mark. Neither does it have any properties for setting the size.

Also, I want to be able to theme my control, so the control needs to have some kind of property that could be set in the skin file, and there is no such property on the standard asp CheckBox. It does have a method for setting properties on the inner input control, however, but as I said, I need a property.

The CheckBox control is rendered inside a span tag, like this:

<span class="checkbox">
  <input id="ContentPlaceHolder1_chkPersistLogin"
         type="checkbox"
         name="ctl00$ContentPlaceHolder1$chkPersistLogin" />
  <label for="ContentPlaceHolder1_chkPersistLogin">
Remember me</label>
</span>

Now, as you can see, if you set the CssClass property of the control to something, then it will be applied to the span, not to the inner controls directly.

So, as I mentioned, the CheckBox control does have a way of accessing the inner input control. It is by using the InputAttributes propertys methods. For example, the following code will add a “class” attribute to the <input type=”checkbox” /> tag:

MyCheckBox.InputAttributes.Add("class", “MyCheckBoxCssClass”);

If I want to set the class on my inner input control, then I could create my own custom control that inherits from the asp CheckBox control. Here’s my CheckBoxPlus class:

using System;
using System.Web;
using System.Web.UI.WebControls;

namespace MyWebApp.WebUI.Common.CustomControls
{
    public class CheckBoxPlus : CheckBox
    {
        private string _inputCssClass;

        public string InputCssClass
        {
            get { return _inputCssClass; }
            set
            {
                _inputCssClass = value;
                this.InputAttributes.Add("class", _inputCssClass);
            }
        }
    }
}

To be able to use my custom control in a page, I need to add a directive to the web forms where I want to use it:

<%@ Register TagPrefix="custom" Assembly="MyWebApp.WebUI" Namespace="MyWebApp.WebUI.Common.CustomControls" %>

Now I can use the control im my page, and set the new property:

<custom:CheckBoxPlus ID="chkPersistLogin" runat="server" Text="Remember me" CssClass="checkbox" />

The last part is to enable theming/skins for the control. The only thing you need to do is to add the same Register directive at the top of the skin file, and then you can create a template for you control in the usual way. Here’s an example skin file:

<%@ Register TagPrefix="cd" Assembly="MyWebApp.WebUI" Namespace="MyWebApp.WebUI.Common.CustomControls" %>
<asp:Button runat="server" />
<asp:TextBox runat="server" />
<asp:Label runat="server" />
<asp:Panel runat="server" HorizontalAlign="Center" />
<cd:CheckBoxPlus InputCssClass="checkboxplus" runat="server" />

When I load my page now, the rendered HTML looks like this:

<span class="checkbox">
  <input id="ContentPlaceHolder1_chkPersistLogin"
         type="checkbox"
         name="ctl00$ContentPlaceHolder1$chkPersistLogin"
         class="checkboxplus" />
  <label for="ContentPlaceHolder1_chkPersistLogin">Remember me</label>
</span>

As you can see, the theme sets the InputCssClass, and thus I am able to control the size of the check mark of the CheckBox control.

2011-02-11

Installing Windows Phone 7 CTP on Windows XP

Source: http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/6657c1ff-45a6-466a-b20d-f5640e3f0c1f/

Thanks to Oran Dennison for this solution.

Please be awear that Microsoft does not support running the Windows Phone 7 CTP Tools on Windows XP. I found this solution, and I am using it at my own risk, as should you.

Workaround for installing Windows Phone 7 CTP on Windows XP:

1.Download the Windows Phone Developer Tools CTP Refresh from here: developer.windowsphone.com 
2.Extract the contents of the setup package by running vm_web.exe /x and choosing a path to extract to
3.Go to the folder you extracted to in step 2 and open the file baseline.dat in notepad
4.Look for the section named [gencomp7788]
5.Change the value InstallOnLHS from 1 to 0
6.Change the value InstallOnWinXP from 1 to 0
7.Save and close baseline.dat
8.Run setup.exe /web from the folder you extracted to in step 2

2011-01-14

Windows x64 knowledge

I have learned about Windows 64-bit:

  • On a 64-bit Windows machine, there are two different locations for programs to be installed:
    • Programs
      • For 64-bit programs
    • Programs (x86)
      • For 32-bit programs
  • There are two different ODBC managers:
    • the 64-bit version is accessed from Control Panel / Administrative Tools
    • the 32-bit version may be found under [SysDrive]:\Windows\SysWOW64
  • Oracle 10g had a problem with the parentheses in the “Programs (x86)” folder name, for which there were released a patch.
  • The BI Development Studio (VS2008) which comes with SQL Server 2008 is 32-bit, and does not have easy access to 64-bit drivers. This goes also for the SSIS Package Designer.
    • If you build for “Any CPU” it might still work.
    • Or you could install both, and define ODBC connections with the same names using both of the ODBC managers.
  • (more info coming soon…. maybe)

64-bit Windows 2008 vs Oracle x64

Ok, so finally after exploring several ways to run a query on Oracle x64, I have succeeded.

First step is to install a 64-bit Oracle Client on the W2k8 server. For me it works with the Oracle 11g InstantClient v. 11.2, connecting to an Oracle 10.x.. database.

I am using a 32-bit developer machine, using the System.Data.OracleClient classes, and everything seems to work.

My connection string is like this:
<connectionStrings>
    <add name=”oracle” 
            connectionString=”Data Source=TNSNAME;UserId=uid;Password=pwd;” />
</connectionStrings>

So everything works nicely, until I move my compiled code to the x64 server.
I now get this error:

Attempt to load Oracle client libraries threw BadImageFormatException.  This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.

Solution:
Before compiling, go into the project properties and set the “Platform target” property to “Any CPU”.
Compile, then copy your assemblies to the server. Looks like an extra DLL-file has been added to my bin-folder (Oracle.DataAccess.dll).

2010-12-16

SoapExceptionWrapper

I wrote this code quite a while ago, but since it’s quite reusable (and very simple) here it is:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.Services.Protocols;
using System.Xml;

namespace SupportLibrary.ExceptionHandling
{

    /// <summary>
    /// Wrapper Class for Soap Exception from JBoss.
    /// Parses the XML in the Detail XML Node, exposing StatusCode and StatusDescription as properties.
    /// </summary>
    /// <example>
    /// int errorCode = -1;
    /// try
    /// {
    ///     WebService.DoSomething();
    /// }
    /// catch(SoapException soapex)
    /// {
    ///     SoapExceptionWrapper wrapper = new SoapExceptionWrapper(soapex);
    ///     int errorCode = wrapper.StatusCode;
    ///     string errorDescription = wrapper.StatusDescription;
    /// }  
    /// </example>
    public class SoapExceptionWrapper
    {
        private SoapException _ex;

        /// <summary>
        /// The XmlNode containing the Detail information about the error.
        /// </summary>
        public XmlNode DetailXml
        {
            get
            {
                return _ex.Detail.FirstChild;
            }
        }

        /// <summary>
        /// Status code from SoapException Detail XML.
        /// </summary>
        public int StatusCode
        {
            get
            {
                string codeStr = "-1";
                if(DetailXml != null && DetailXml.ChildNodes.Count > 0)
                    codeStr = DetailXml.SelectSingleNode("StatusCode").InnerText;
                int codeInt = -1;
                int.TryParse(codeStr, out codeInt);
                return codeInt;
            }
        }

        /// <summary>
        /// Status description from SoapException Detail XML.
        /// </summary>
        public string StatusDescription
        {
            get
            {
                if (DetailXml != null && DetailXml.ChildNodes.Count > 0 && DetailXml.SelectSingleNode("StatusDescription") != null && DetailXml.SelectSingleNode("StatusDescription").InnerText != "")
                {
                    return DetailXml.SelectSingleNode("StatusDescription").InnerText;
                }
                return _ex.Message;
            }
        }

        /// <summary>
        /// Constructor using default values.
        /// </summary>
        /// <param name="soapex"></param>
        public SoapExceptionWrapper(SoapException soapex)
        {
            _ex = soapex;
        }
    }
}

2010-09-27

Generic cache manager

The following class is a generic cache manager. It requires a reference to System.Web.

public static class CacheManager
{
    public static T GetObject<T>(string key)
    {
        if (System.Web.HttpRuntime.Cache.Get(key) != null) return (T)System.Web.HttpRuntime.Cache.Get(key);
        return default(T);
    }

    public static void AddObject<T>(T customObject, string key, TimeSpan duration)
    {
        if (System.Web.HttpRuntime.Cache.Get(key) == null)
            System.Web.HttpRuntime.Cache.Insert(key, customObject, null, System.Web.Caching.Cache.NoAbsoluteExpiration, duration);
    }
}

2010-09-23

SQL Server 2008: No connection could be made because the target machine actively refused it

An old problem which still causes me some trouble now and again.

So I got the following error:

No connection could be made because the target machine actively refused it. Microsoft SQL Server Error 10061

So first thing to check is wether or not the server is set up to accept remote connections.

  1. Open up SQL Server Management Studio (SSMS).
  2. Right-click on the server instance, select Properties…
  3. Click on the “Connections” option on the left side.
  4. Verify that the “Allow remote connections to this server” option is checked.

If it was not enabled, you might try to restart the sql server service by running “NET STOP mssqlserver” and “NET START mssqlserver” in a command window. You need to restart the service for any configuration changes to take effect.

Second thing you might check is if the server has enabled TCP/IP.

  1. Open SQL Server Configuration Manager.
  2. Expand the SQL Server Network Configuration node.
  3. Make sure that TCP/IP is enabled.

Remember again that you must restart Sql Server for changes to be effective.

Final thing is to go into the Surface Area configuration and enable the functionality you need. This used to be a separate configuration tool in SQL Server 2005, but now it is integrated into SSMS.

  1. Open up SQL Server Management Studio (SSMS).
  2. Right-click on the server instance, select Facets…
  3. Select the “Surface Area Configuration” facet from the dropdown at the top.
  4. You may at least want to set the “AdHocRemoteQueriesEnabled” to true, and maybe some of the other options as well.

Remember to restart SQL Server.

2010-09-13

Pregnancy Ticker Screen Saver

I have created a HTML page to be used with the HTML Screen Saver from http://myweb.tiscali.co.uk/djmclean/htmlscreensaver.html.

The actual screen saver must first be installed from the link above.

After it has been installed, create a HTML Page and paste the following markup into it, and then save it somewhere (preferably in a dedicated new directory).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body bgcolor="#0080C0" topmargin="0" leftmargin="0" rightmargin="0" bottommargin="0" scroll="no">
<div id="tickerDiv" style="width:1600px;height:1000px; background-image:url('scrback.jpg'); background-repeat: no-repeat; background-position:center center; border-width: 0; margin: 0 0 0 0;" >
<table id="kwsTickerLayoutTable" border="0" cellspacing="2" cellpadding="1" style="background-color:#FFEEFF;text-align:left;position:absolute;">
<tr><td rowspan="3" style="background-color:green;"><a id="kwsTickerCountdownUrl" href="" style="border:0;"><img id="kwsTickerCountdownImage" width="100px" alt="" src="" style="border: 1px solid #EEDDEE;" /></a></td><td style="font-style:normal; font-family: Arial; font-size: x-large; font-weight: bold; font-variant: normal; color: #008080;"><label id="kwsTickerCountdownText1">test</label></td></tr>
<tr><td style="font-style:normal; font-family: Arial; font-size: x-large; font-weight: bold; font-variant: normal; color: #008080;"><label id="kwsTickerCountdownText2">test</label></td></tr>
<tr><td style="font-style:normal; font-family: Arial; font-size: x-large; font-weight: bold; font-variant: normal; color: #008080;"><label id="kwsTickerCountdownText3">test</label></td></tr>
</table>
</div>
</body>
<script language="javascript" type="text/javascript">
    var now = new Date(); //today
    var dob = new Date(2011, 2, 9); //date of birth
    var doc = new Date(2010, 5, 1); //start date of pregnancy
    var one_day = 1000 * 60 * 60 * 24; //milliseconds in one day
    var days_total = Math.ceil((dob.getTime() - now.getTime()) / (one_day)); //number of days left
    var weeks = Math.floor(days_total / 7); //number of weeks left
    var days = days_total % 7; //number of days in addition to the weeks left
    var days_gone_total = Math.ceil((now.getTime() - doc.getTime()) / one_day); //number of days gone
    var weeks_gone = Math.floor(days_gone_total / 7); //number of weeks gone
    var days_gone = days_gone_total % 7; //number of days in addition to the weeks gone
    var lab1 = document.getElementById('kwsTickerCountdownText1'); //get label 1
    var lab2 = document.getElementById('kwsTickerCountdownText2'); //get label 2
    var lab3 = document.getElementById('kwsTickerCountdownText3'); //get label 3
    var img = document.getElementById('kwsTickerCountdownImage'); //get image element
    var url = document.getElementById('kwsTickerCountdownUrl'); // get url element of image element
    lab1.innerHTML = (weeks_gone + 1) + 'th week';
    if (days_gone > 0) { lab2.innerHTML = weeks_gone + ' weeks and ' + days_gone + ' days on the way.'; } else { lab2.innerHTML = weeks_gone + ' weeks on the way.'; }
    if (days > 0) { lab3.innerHTML = 'Only ' + weeks + ' weeks and ' + days + ' days left!'; } else { lab3.innerHTML = 'Only ' + weeks + ' weeks left!'; }
    img.setAttribute('src', 'http://images.3dpregnancy.com/en/2D/200/' + weeks_gone + '-weeks-pregnant.jpg');
    url.setAttribute('href', 'http://3dpregnancy.parentsconnect.com/calendar/' + weeks_gone + '-weeks-pregnant.html');

    var tickerDiv = document.getElementById('tickerDiv');
    tickerDiv.style.width = screen.width;
    tickerDiv.style.height = screen.height;

    window.setTimeout("Tick()", 500, "javascript");
</script>
<script language="javascript" type="text/javascript">
    function Tick() {
        var tabl = document.getElementById('kwsTickerLayoutTable');
        var x = Math.floor(Math.random() * (screen.width - tabl.offsetWidth)) + 'px';
        tabl.style.left = x;
        var y = Math.floor(Math.random() * (screen.height - tabl.offsetHeight)) + 'px';
        tabl.style.top = y;
        window.setTimeout("Tick()", 2000, "javascript");
    }
</script>
</html>

If you want to have a background image, save a JPG-file called “scrback.jpg” into the same directory. If you don’t want a background image (if you are concerned about burn-in etc.), you may need to remove the following text: background-image:url('scrback.jpg') from the markup above.

Lastly, go into the screen saver options on your computer and configure the HTML file you created as the one you want your HTML screen saver to use.

Pregnancy ticker

The following HTML is a pregnancy ticker. The HTML fetches an image from http://www.3dpregnancyticker.com. Click on the image to go to the web site. To put in your own due date you will need to change the values for the “dob” and “doc” variables. It may be used as a desktop item on Windows. I have also used it on a HTML Screen Saver.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
<div style="height:100%;width:100%;vertical-align:middle;text-align:center;background-color:MidnightBlue;">
<table id="kwsTickerLayoutTable" border="0" cellspacing="2" cellpadding="1" style="background-color:#FFEEFF;text-align:left;">
<tr><td rowspan="3" style="background-color:green;"><a id="kwsTickerCountdownUrl" href="" style="border:0;"><img id="kwsTickerCountdownImage" width="100px" alt="" src="" style="border: 1px solid #EEDDEE;" /></a></td><td style="font-style:normal; font-family: Arial; font-size: x-large; font-weight: bold; font-variant: normal; color: #008080;"><label id="kwsTickerCountdownText1">test</label></td></tr>
<tr><td style="font-style:normal; font-family: Arial; font-size: x-large; font-weight: bold; font-variant: normal; color: #008080;"><label id="kwsTickerCountdownText2">test</label></td></tr>
<tr><td style="font-style:normal; font-family: Arial; font-size: x-large; font-weight: bold; font-variant: normal; color: #008080;"><label id="kwsTickerCountdownText3">test</label></td></tr>
</table>
</div>
</body>
<script language="javascript" type="text/javascript">
    var now = new Date(); //today
    var dob = new Date(2011, 2, 9); //date of birth
    var doc = new Date(2010, 5, 1); //start date of pregnancy
    var one_day = 1000 * 60 * 60 * 24; //milliseconds in one day
    var days_total = Math.ceil((dob.getTime() - now.getTime()) / (one_day)); //number of days left
    var weeks = Math.floor(days_total / 7); //number of weeks left
    var days = days_total % 7; //number of days in addition to the weeks left
    var days_gone_total = Math.ceil((now.getTime() - doc.getTime()) / one_day); //number of days gone
    var weeks_gone = Math.floor(days_gone_total / 7); //number of weeks gone
    var days_gone = days_gone_total % 7; //number of days in addition to the weeks gone
    var lab1 = document.getElementById('kwsTickerCountdownText1'); //get label 1
    var lab2 = document.getElementById('kwsTickerCountdownText2'); //get label 2
    var lab3 = document.getElementById('kwsTickerCountdownText3'); //get label 3
    var img = document.getElementById('kwsTickerCountdownImage'); //get image element
    var url = document.getElementById('kwsTickerCountdownUrl'); // get url element of image element
    lab1.innerHTML = (weeks_gone + 1) + 'th week';
    lab2.innerHTML = weeks_gone + ' weeks and ' + days_gone + ' days on the way.';
    if (days > 0) { lab3.innerHTML = 'Only ' + weeks + ' weeks and ' + days + ' days left!'; }
    else { lab3.innerHTML = 'Only ' + weeks + ' weeks left!'; }
    img.setAttribute('src', 'http://images.3dpregnancy.com/en/2D/200/' + weeks_gone + '-weeks-pregnant.jpg');
    url.setAttribute('href', 'http://3dpregnancy.parentsconnect.com/calendar/' + weeks_gone + '-weeks-pregnant.html');
</script>
</html>

2010-06-14

SQL Server 2008 Client Tools Install Pain

In this blog post http://nomisit.wordpress.com/2009/04/21/installing-sql-server-2008-client-tools-what-a-pain/ it is described how you need to upgrade Visual Studio 2008 to SP1 if you are installing any of these…

  • BIDS
  • Management tools (Basic or Full version)
  • Integration Services
  • … and you have previously installed VS2008, then you will need to upgrade it to SP1.

    I did install a trial version of VS2008 but now I have uninstalled everything, but still getting the same failed requirement.

    So now I am trying to install SP1, even if I don’t know what products it could be upgrading since I removed them all. Perhaps it is something like a C++ runtime or something that was left behind by the uninstaller?

    The SP1 installer seemed to be stuck on “WebDesignerCore_KB950278”. But proceeded after quite a while (20 minutes, maybe more).

    Then it took a long time to install “VS90sp1-KB945140-X86-ENU”.

    I got a Fatal Error at the end of the install, so now I don’t know what was installed or not. So either try to reinstall SP1 or try to install the client tools?

    Tried to install client tools, and to my surprise it succeeded!