
Creating splash screens in .net 3.5 SP1

This pause introduces uncertainty into the user's perception of the program: did the program start or not?
You can solve this problem by showing the splash screen immediately after launch. This will give a physical response immediately after launching the application and create the illusion of faster loading.
How to do this is written under the cut.
Why is the application loading so long
This is due to the fact that .net libraries, which occupy about 20 megabytes, are not loaded into memory when Windows starts. The .net Framework dynamically loads the necessary libraries when the program starts. If we look at Output in the studio when the program starts, we can see it:
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_32 \ mscorlib \ 2.0.0.0__b77a5c561934e089 \ mscorlib.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ Microsoft.VisualStudio.HostingProcess.Utilities \ 9.0.0.0__b03f5f7f11d50a3a \ Microsoft.VisualStudio.HostingProcess.Utilities.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ PresentationFramework \ 3.0.0.0__31bf3856ad364e35 \ PresentationFramework.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'SplashDemo.vshost.exe' (Managed): Loaded 'D: \ work \ Visual Studio 2008 \ Projects \ SplashDemo \ bin \ Debug \ SplashDemo.exe', Symbols loaded.
Step into: Stepping over non-user code 'System.Windows.SplashScreen.SplashScreen'
Step into: Stepping over non-user code 'SplashDemo.App.App'
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ System.Configuration \ 2.0.0.0__b03f5f7f11d50a3a \ System.Configuration.dll ', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
Step into: Stepping over non-user code 'SplashDemo.App.InitializeComponent'
'SplashDemo.vshost.exe' (Managed): Loaded 'C: \ Windows \ assembly \ GAC_MSIL \ PresentationFramework.Aero \ 3.0.0.0__31bf3856ad364e35 \ PresentationFramework.Aero.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
How it was decided before
It was necessary to dance with a tambourine and run native code before starting the application. And then stop him somehow. The Quicksplash commercial component offers to delete a file from a specified folder after loading your application. The option is somewhat inconvenient. The rest are even worse.
How is it solved now
With the advent of .net 3.5 sp1, everything is done in just two clicks. Only images in the following formats are supported: BMP, GIF, JPEG, PNG and TIFF. PNG has alpha channel support.
Option number 1
The easiest option. It is sufficient in 99% of cases. To create a screensaver, you need to add an image to the project:

And in the Properties window of the added file, set the Build Action parameter to SplashScreen .

That is all that is needed.
At build time, the following lines will be added to the App.g.cs file :
SplashScreen splashScreen = new SplashScreen("splash.png");
splashScreen.Show(true);
* This source code was highlighted with Source Code Highlighter.
We will analyze them a bit later.
Option number 2a
The second option is not much different from the first: we just do it ourselves. To do this, add a picture to the project. Open App.xaml (not App.xaml.cs ) and add a new handler for the StartUp event:

Go to the App.xaml.cs file , look for the newly created method and add it with the following lines:
private void AppStartUp(object sender, StartupEventArgs e)
{
var splash = new SplashScreen("splash.png");
splash.Show(true);
}
* This source code was highlighted with Source Code Highlighter.
Let's take them apart. The first line creates a new instance of the SplashScreen class. The constructor has a single parameter - the file name:
var splash = new SplashScreen("splash.png");
* This source code was highlighted with Source Code Highlighter.
In the second line, we call the Show method (bool autoClose) . If the value of the argument is true, then the splash screen will close automatically after loading the application. Otherwise, you must call the Close method .
splash.Show(true);
* This source code was highlighted with Source Code Highlighter.
Option number 2b
Practice has shown that there are situations when it is necessary to show a splash screen not only at boot time, but also, for example, right after the authorization window:
public Window1()
{
ShowAuthorizationDialog();
InitializeComponent();
}
* This source code was highlighted with Source Code Highlighter.
Due to the fact that InitializeComponent () is called after authorization, there is an additional loading of libraries that are used in the code of the main application, but are not used in the authorization window. This causes a delay before the main window appears. In order to avoid this effect, you can do the following:
public Window1()
{
ShowAuthorizationDialog();
var splash = new SplashScreen("spalsh.png");
splash.Show(false);
InitializeComponent();
splash.Close(TimeSpan.FromMinutes(0.5));
}
* This source code was highlighted with Source Code Highlighter.
Here is the only new line:
splash.Close(TimeSpan.FromMinutes(0.5));
* This source code was highlighted with Source Code Highlighter.
The Close () method closes the splash screen with a fading effect. As a parameter, the method takes the time interval during which the screen saver will "go out".
Known bugs
In the process of use, a black background slipped a couple of times instead of transparency. Reasons have not yet been identified. Win32Exeption
occurs when switching to another application at a time when the screen saver goes out. You can catch by surrounding the Close () method with a try ... catch block .
Conclusion
Using the screen saver in your program makes it more comfortable and humane in relation to the user. Allows you to avoid unnecessary mental aggression against the developer. :-)
UPD: This applies only to WPF applications.
UPD2: Moved to the .NET blog . Thanks.