navigation
 Tuesday, July 17, 2007

There is a pattern to these errors.  Same asp.net source, same database, same IIS version, same Visual Studio version, same components version, but still some chunk of JavaScript is absent without leave. The actual error messages tend to be new each time, but at least the pattern is recognizable. The reason is that the missing JavaScript functions live in webresource.axd, webresource.axd is handled by an aspnet_isapi.dll, and chances are you are missing a mapping for "axd" in your IIS configuration for your web site. To fix:

  • In the IIS Microsoft Management Console snap-in, right-click the virtual directory and select Properties.
  • On the Virtual Directory tab click the Configuration button. 
  • On the Mappings tab of the Application Configuration dialog click the Add button. This brings you to the Add/Edit Application Extension Mapping dialog. Enter for the Executable the full path to aspnet_isapi.dll located in .NET framework directory.  In this case the path was C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll. Set the Extension to be ".axd".  Don't forget the dot or the dialog will not let you proceed. Uncheck the "Check that file exists" checkbox.
  • If the OK button doesn't become enabled, there's a weirdity here (in the tech support business we used to call these "issues", in the real world we call it a "bug").  Click the Executable textbox entry and the OK button should become enabled.

Cycle the website and try again.  Different flavors of this problem occur periodically, so tag this page for later and save yourself some pain.

posted on July 17, 2007  #    by Noel Rice  Comments [0]
 Sunday, July 15, 2007

A while back I was trying to figure out how to make F1 bring up a custom help window in our web application ActiveFocus. It is easy enough to trap a keypress and open a window showing the help, but to my frustration, after popping up the new window, the built in Internet Explorer help window popped up too!

I tried various variations of cancelling the kepress event, but nothing seems to work. This is for instance how I cancel Ctrl+F (which normally pops up IEs built in Find dialog, but I wanted it to show a custom search dialog instead) :

<script type="text/javascript">

function onKeyDownH(e)
{
  e = window.event;

  var ctrl = (e.ctrlKey) ? true : false;
  if (ctrl == true )
  {
    if ( e.keyCode == 70)
    {
      e.returnValue = false;
      e.keyCode = 0;
      ShowSearchPage();
    }
  }
}

function onloadH(e)
{
  document.onkeydown = onKeyDownH;
  return true;
}

window.onload = onloadH;

</script>

This cancelling approach by the way does work for other keypresses, just not F1, which has some kind of special internal handing. After much head scratching I finally stumbled across this simple solution:

<body onhelp="ShowHelp(); return false;">

Here, ShowHelp does the actual showing of the help window.

Simple, huh? If anyone knows how to make this cross browser compatible I am all ears!

posted on July 15, 2007  #    by John Waters  Comments [1]
 Saturday, July 14, 2007

You may run into the 15023 error if you restore a MS SQL database from backup.  You expect a restored database to be in exactly the same state as the backup, but the login fails for a user that had permissions in the backed up database.  When you use the "User Mapping" SQL Management Studio functionality to allow the user permissions to the new database, you receive the 15023 error.  This is caused by Security identification numbers (SID) that are mismatched or 'orphaned' in the sysusers table. 

The SQL Server stored proc sp_change_users_login locates and fixes these records.  Run it with a single parameter 'Report' to get a listing of abandoned user names and corresponding SIDs:

exec sp_change_users_login Report

The 'Update_One' parameter will reconnect a single login:

exec sp_change_users_login Update_One, 'MyLogin', 'MyLogin'

You can find more info about this issue at:

http://support.microsoft.com/kb/246133

http://support.microsoft.com/kb/240872

This next blog expands on the available parameters for sp_change_users_login:

http://blog.sqlauthority.com/2007/02/15/sql-server-fix-error-15023-user-already-exists-in-current-database/

Also, try checking out the source for sp_change_users_login found in the Sql Server Management Studio under Databases | System Databases | Master | Programmability | Stored Procedures | sp_change_users_login.

posted on July 14, 2007  #    by Noel Rice  Comments [0]
 Friday, July 13, 2007

Like many developers, I have both VS2003 and VS2005 installed on my machine. I had also placed a shortcut to the Visual Studio  command prompt in my programs menu. A couple of days ago, I had the opportunity to write my first Windows service application. I got everything set the way I wanted, and it was time to install. So, I opened up the VS command prompt, and typed in the magic chant "installutil servicename.exe". And fairly promptly got the error "Exception occurred while initializing the installation: System.BadImageFormatException: the format of the file 'servicename.exe' is invalid...".

If you're encountering the same error, make sure that you're using the correct installer. For me, it turned out that I was using the VS2003 installer. As soon as I switched to the installer from VS2005 (using the correct command prompt), everything worked just fine. It took me a while to track this down - perhaps this will save you some time.

posted on July 13, 2007  #    by Rick Miller  Comments [2]
 Thursday, July 12, 2007

While working with Visual Studio and wishing that feature X existed, I decided to delve into the Visual Studio Extensibility layer and see what it can do.  There are 3 main ways to extend the VSIDE which are Macros, Plugins, and Packages so I opted to play with managed packages (I like C# and wanted full integration into the IDE).

After downloading the Visual Studio 2005 SDK and completing development of my package I needed to deploy it.  I ran into a number of issues deploying my package, mostly related to issues with the Package Load Key.  Following are the steps that I came up with for deploying a package.

  1. Create a new VSIP membership account if you do not already have one (go to the VSIP affiliate site to sign up if you are not a member yet)
  2. Login using your passport account at the vsip members
  3. Once logged in, you must Create a new product
    1. Click on the Products link
    2. Click on the Create New Product link and fill out the information for your package
  4. After your product is created, click on the View/Request PLK link
  5. Fill in the information as it appears in your VSPackage and click the Request PLK button
  6. Microsoft will review your product and notify you that the PLK has been approved or denied
  7. If the PLK has been approved, log back into your VSIP member account, click on Products and then View/Request PLK
  8. Add a new numbered resource to your package with the PLK as its value
  9. Modify the ProvideLoadKey attribute in your package source to reference the resource number for your PLK

Microsoft requires that each deployed Package be given a key generated by and registered with Microsoft.  The generated key is called a Visual Studio Package Load Key, or PLK and must be requested from your VSIP, or Visual Studio Industry Partner, account (Note that if you are not a VSIP member you must sign up).  The PLK is a digest based on information specific to the Package that you have created (Package GUID, Package Name, Product Name, Company Name) allowing for a higher probability of unique values between packages.  The PLK also allows Microsoft to keep track of all released 3rd-party packages via their signature.  Be aware that PLKs are finicky so you must be sure to use the EXACT same information for both the Package and what was used to generated a PLK.

    Here are some useful links I came across regarding PLKs when I was getting my package ready for deployment:
    posted on July 12, 2007  #    by Adam Markowitz  Comments [0]
     Sunday, July 08, 2007

    SQL Management Objects (SMO) is something of a Swiss army knife that lets you traverse meta data, automate backup and restore, and otherwise manage SQL Server 2005 through .NET code.  For instance, to perform the classic database hierarchy walk use the SmoApplication object and enumerate the servers.  First you need to reference the Smo assemblies:

    Microsoft.SqlServer.ConnectionInfo.dll
    Microsoft.SqlServer.Smo.dll
    Microsoft.SqlServer.SmoEnum.dll

    Then call the SmoApplication EnumAvailableSqlServers() method, passing 'true' to list only local servers:

    1
    DataTable tblServers = SmoApplication.EnumAvailableSqlServers(true);

    EnumAvailableSqlServers() may not work if you don't have a network connection, but you can use the RegisteredServers collection property instead. This will work without network connection and will pick up server instances for SQL 2000/2005, SQL Express and MSDE. Here the heirarchy follows the expected pattern of Server/Database/Table:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    foreach (RegisteredServer registeredServer in SmoApplication.SqlServerRegistrations.RegisteredServers)
    {
    Server server = new Server(registeredServer.Name);
    Console.WriteLine("Server: {0} Version: {1}",
    registeredServer.Name, server.PingSqlServerVersion(server.Name).Major);

    foreach (Database database in server.Databases)
    {
    if ((!database.IsSystemObject) && (database.IsAccessible))
    {
    Console.WriteLine("Database: {0}", database.Name);

    foreach (Table table in database.Tables)
    {
    Console.WriteLine("Table: {0} Rows: {1}", table.Name, table.RowCount);
    }
    }
    }
    }

    There are a large number of collections and enumerating methods, for example: stored procedures, user defined types, roles, rules, schemas, locks and permissions.  SMO works against Sql Server earlier than 2005, but some methods may not be supported.  You can handle that by checking the sql version:

    1
    2
    3
    4
    5
    6
    7
    if (server.PingSqlServerVersion(server.Name).Major > 8)
    {
    foreach (UserDefinedDataType udf in database.UserDefinedDataTypes)
    {
    Console.WriteLine("Type: {0}", udf.Name);
    }
    }

    A nifty SMO bonus is that objects Database and downwards in the hiearchy have a Script StringCollection property.  Script is pre-populated with T-SQL and can be used to recreate objects.

    SMO provides DBA automation functionality like backup/restore and create/drop databases. These operations depend on the SMO Server object.  The constructor for Server can have a) no parameters for your local server, b) a server name only, or c) a ServerConnection object in case you need to supply user name and password.

    1
    2
    ServerConnection serverConnection = new ServerConnection("MyMachine", "sa", "MyM@ch1n3");
    Server raServer = new Server(serverConnection);

    Here is an example of creating a new database to be used as a backup location:

    1
    2
    3
    4
    5
    6
    7
    8
    static Database CreateBackupDatabase(Server server, string databaseName)
    {
    string backupDatabaseName = databaseName + "_" + DateTime.Now.ToString("yyMMddHHmmffffff");
    Database backupDatabase = new Database(server, backupDatabaseName);
    Console.WriteLine("Creating new database {0}", backupDatabase.Name);
    backupDatabase.Create();
    return backupDatabase;
    }

    The backup operation requires a backup "device", in this case a file that will be used to store the backup.  Assign an SMO Database object to be backed up, add the backup device to its list of devices and call the SqlBackup() method.  You may also want to assign event handlers for PercentComplete and Complete events.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    static void DoBackup(Server server, string databaseName, Database backupDatabase)
    {
    Console.WriteLine("Backing up {0}", databaseName);

    BackupDeviceItem backupDevice =
    new BackupDeviceItem(databaseName + ".bak", DeviceType.File);

    Backup backup = new Backup();
    backup.Database = databaseName;
    backup.Devices.Add(backupDevice);
    backup.PercentComplete += new PercentCompleteEventHandler(InProgress);
    backup.Complete += new ServerMessageEventHandler(Complete);
    backup.SqlBackup(server);
    }

    static void InProgress(object sender, PercentCompleteEventArgs e)
    {
    Console.WriteLine("Percent complete: {0}", e.Percent);
    }

    Restoring can sometimes be trickier due to the original database having a strangle-hold on the physical data and log files.  To work around this use the Restore RelocateFiles property to map new file names and locations. Also notice that to get the physical file path we use the Database object's FileGroups property, drill down into the Files and use the path of the first file in the list.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    static void DoRestore(Server server, string databaseName, Database backupDatabase)
    {
    Console.WriteLine("Restoring {0}", backupDatabase.Name);
    Restore restore = new Restore();
    restore.Database = backupDatabase.Name;
    restore.ReplaceDatabase = true;
    string backupPath = Path.GetDirectoryName(backupDatabase.FileGroups[0].Files[0].FileName);
    string dataPath = string.Format("{0}\\{1}.mdf", backupPath, backupDatabase.Name);
    restore.RelocateFiles.Add(new RelocateFile("Falafel", dataPath));
    restore.RelocateFiles.Add(new RelocateFile("Falafel_log", Path.ChangeExtension(dataPath, ".ldf")));
    BackupDeviceItem backupDevice =
    new BackupDeviceItem(databaseName + ".bak", DeviceType.File);
    restore.Devices.Add(backupDevice);
    restore.PercentComplete += new PercentCompleteEventHandler(InProgress);
    restore.Complete += new ServerMessageEventHandler(Complete);
    restore.SqlRestore(server);
    }

    Thats a few of the things SMO can do for you. It's not a replacement for T-SQL, but if you need access to meta-data, automation or other DBA tasks from managed code, then the SMO namespace may be worth exploring. BTW, you can also use SMO in PowerShell directly, wrapped in commands or as the infrastructure for PowerShell providers.

    posted on July 8, 2007  #    by Noel Rice  Comments [2]
     Friday, July 06, 2007
    It’s a big week for the staff at Falafel who has been cooking up a course certain to whet the appetite for project teams everywhere. With the release of ActiveFocus, the Falafel team has once again demonstrated their ability to deliver as promised.
    posted on July 6, 2007  #    by Lino Tadros  Comments [0]
     Thursday, July 05, 2007
    SAN JOSE, Calif. July 5, 2007 -- Falafel Software, an industry leader in consulting, training, and software development is pleased to announce the hiring of Steve Trefethen as Software Architect. Trefethen, former R&D Staff Engineer at CodeGear, Borland’s Developer Tools Group, has over 15 years of experience working along side some of the world’s leading software developers.
    posted on July 5, 2007  #    by Lino Tadros  Comments [0]