We have been having some strange problems on production installs. Things like screens clearing when they shouldn’t, applications slowing down when they didn’t before, and people’s computers running slower and slower until they close our application. When I was finally informed of this, I knew it had to be memory leaks.
So I fired up the excellent MemProfiler, I started digging into the issues. Aside from some of the other stupidity I was doing, I found a problem with a vendor’s component. We use Developers Express controls for EVERYTHING and we love them, not just the controls, but the company. When I found this issue with XtraReports not being GC’d after a dispose, I immediately created a small sample for them and submitted a ticket.
Less than 2 days later, they already have it fixed and ready to rock in the latest version. Not only am I impressed, but I am put at ease knowing that if a problem comes up, they are there to not only fix it, but fix it quickly and get it out to people.
This also happened a few months ago when their ASPxThemeDeployer wouldn’t work on my x64 Vista machine. I peeked at their code and saw why. Reported it and the VERY NEXT DAY they had a solution to the problem and pushed out an update.
I don’t have to worry. I know I am taken care of.
I’m reading a pretty well written book by Adam Nathan called Windows Presentation Foundation Unleashed. I am on the hunt for more in depth knowledge of WPF and how it is going to affect me, if at all.
In my search of an answer of the question ‘Why?’ I already found 2 answers.
1. WPF uses DirectX to render the controls on screen. This pushes most of the UI processing onto the GPU (Video Card) instead of the CPU. This should speed up Windows applications a bit and also allow UI elements to be processing while business logic elements are running (think progress bars).
2. Using a WPF application in Remote Desktop will allow all visual elements to be processed using DirectX on the CLIENT PC. This means that if I connect to my machine at work from home, all WPF applications will be rendered using my video card instead of my work PC’s video card. How cool is that?! That will make using remote desktop faster as well. I have already experienced the Remote Desktop application slowdown because of screen redraws and control hang ups because of nasty UI elements. This would fix those problems.
I will continue to post new things as I find them. Little things like being able to write an XAML document and open it in IE without having to compile is a cool feature, but one I’m not interested in. So plan on only seeing REALLY cool features here.
Pretty cool… Although my REAL first thought after using it was, “Why?”
The reason I ask why is because as I am looking at the available controls and what it looks like on screen once I run the test application, I am really presented with the same looking form as if I just used a regular Windows Forms control. This doesn’t mean that I think it’s useless already. Heck, I only spent about 20 minutes with it. I haven’t even read up on it as much as I should have before even posting this.
So, let it be known that my research into WPF has started with a resounding, “What is this supposed to accomplish?”
Here is the problem in a nutshell: You have a custom client application that uses SQL Server 2005 Express. The server installation is a little bit to be desired. First, you have to install SQL Server Express, then you have to configure the options (unless you did command line options), then you have to execute the scripts to create your database, tables, and possibly populate it with some data. Or conversely, execute scripts or install and use the management console to attach a database. Messy, at best.
So what if you want to have a single installation program that will install all the prerequisites (.Net), then install SQL Server 2005 with your custom options (instance name for example), and then have it execute scripts and fill it with data? After working at it for hours, I came to the conclusion that you could be out of luck. Until I did some reconfiguring.
First things first, you need to get SQL Server Express to install properly. I struggled with this for a while, until I had the bright idea of using a bootstrapper… But can’t we use the one that comes with the Visual Studio Package and Deployment Wizard? Yes you can!
Go into your Visual Studio 8 folder and find the SDK/v2.0/Bootstrapper/Packages folder. Make a copy of the SqlExpress folder and name it something like, MyAppSqlExpress. Inside that folder, there is a product XML file. Edit that product.xml file and change the product code. Mine was Microsoft.Sql.Server.Express.1.0 and I changed it to MyAppName.Microsoft.Sql.Server.Express.1.0 … Just change the MyAppName to the app name of the product it goes with. You will also see a En folder for the English installation. The package.xml file is the one you want to edit in that folder. The first item to edit, is the arguments line. This passes arguments to the SqlExpr32.exe file (the setup for Sql Express). The arguments are the same as any other SQL Express install… So change it to be something like this:
Arguments='-q /norebootchk /qb reboot=ReallySuppress addlocal=all INSTANCENAME=MyApp SECURITYMODE=SQL SAPWD=MyStrongPassword DISABLENETWORKPROTOCOLS=0 SQLAUTOSTART=1'
This will do a silent installation of SQL Server Express using all protocols, a custom instance name (MyApp), turn on the SQL security mode and specify a strong SA password.
Next, there is the strings block at the bottom. Edit the StringName “DisplayName” to look like this:
MyApp SQL Server 2005 Express Edition
Save it, and go into your setup and deployment project you created, go to the project properties, then to the prerequisites, and in the list you should now see your custom install of SQL Server Express!
This does work, I just tested it out today.
So that solves problem #1. What about the problem of executing scripts? That seems to be the easy part… From my earlier post you can incorporate that code into a custom action.
Create a new project, and select Installer Class from the templates. This creates a new installer class for you to augment.
Private Sub ExecuteSQL(ByVal SQL As String, _ ByVal ConnectionString As String) Dim srv As New Server(New ServerConnection( _ New SqlClient.SqlConnection(ConnectionString))) srv.ConnectionContext.ExecuteNonQuery(SQL) srv.ConnectionContext.Disconnect() End Sub Private Sub BulkLoad(ByVal ConnectionString As String, _ ByVal TableName As String) Dim bulk As New SqlClient.SqlBulkCopy(ConnectionString, _ SqlClient.SqlBulkCopyOptions.KeepIdentity) Dim ds As New DataSet Dim path As String = My.Application.Info.DirectoryPath ds.ReadXmlSchema(path & "\" & TableName & ".xsd") ds.ReadXml(path & "\" & TableName & ".xml") bulk.BulkCopyTimeout = 0 bulk.DestinationTableName = TableName bulk.WriteToServer(ds.Tables(TableName)) bulk.Close() End Sub Public Overrides Sub Install(ByVal stateSaver As _ System.Collections.IDictionary) MyBase.Install(stateSaver) Dim ConnBuilder As New SqlClient.SqlConnectionStringBuilder() ConnBuilder.UserID = "sa" ConnBuilder.Password = "MyStrongPassword" ConnBuilder.DataSource = "localhost\MyApp" ConnBuilder.InitialCatalog = "master" ExecuteSQL(My.Resources.CreateDatabaseSQL, _ ConnBuilder.ConnectionString()) ConnBuilder.InitialCatalog = "MyDatabase" BulkLoad(ConnBuilder.ConnectionString(), "MyTable") End Sub
In this example, I just stored the data files (an XML data file and an XSD schema file) in the setup project, which gets installed along with the custom installer DLL. The create database SQL stuff was all saved as a store resource in the installer class project. I did this so that some of the structure was hidden, which may or may not be an issue for others.
Now, add the custom action to a setup project and you are finished!