I'm currently trying to determine the available disk space from my Silverlight application.
My app can download a lot of data (video files) and obviously, this can fail if the disk space isn't there.
I know I can catch exceptions on writes, but that will not lead to a very user-friendly experience, because the information will come too late and cause useless waits.
In regular .NET, I would be using DriveInfo (see How do I retrieve disk information in C#? for an example), but that class isn't present as of Silverlight 5, even in elevated trust mode.
So, is there a way to determine the available space on a drive in Silverlight?
Update:
I'm fine with requiring Elevated Priviledges for my application.
I'm also fine with Silverlight 5 only solutions.
I need something that works on both Windows and Mac OS, so PInvoke/COM interop is not an option.
There has been filebrowser demos out there written in Silverlight but they would run with elevated trust.
That means that you would have to make the user immediately suspicious of your application when they first run it.
It's probably a better user experience to just have a well worded error message for when the user runs out of space.
Another option would be to try an increase the isolated storage quota by the size of the biggest video available.
http://msdn.microsoft.com/en-us/library/system.io.isolatedstorage.isolatedstoragefile.increasequotato(v=vs.95).aspx
Then when that fails just let the user know that no more space can be allocated for the app had that he may need to delete older videos.
I'm adding my answer here to sum up my discoveries:
TL/DR: there is no easy way to get available disk space in Silverlight 5 that is cross-platform (Windows/Mac OS).
You can't get available disk space with standard Silverlight calls. DriveInfo is missing from Silverlight 5, elevated privileges don't come into account here.
Quota is useless for that kind of issue, it doesn't take into account available disk space.
There are workarounds for Windows only, requiring elevated trust, using P/Invoke into Win32.
For a detailed support of filesystem, see this article: http://www.codeproject.com/KB/silverlight/FileExplorerInSilverlight.aspx
Fall-back is to check for exceptions when writing files and present the user with a message at the time of writing. People have also suggested pre-writing the file when the download start to ensure sufficient disk space.
Related
I've seen several questions that are the opposite of this; "How do I disable virtualization?" That is not my question. I want to force an application to run with virtualization enabled.
I have an application that ran just fine under Windows XP, but, because it writes its configuration to its working directory (a subfolder of "C:\Program Files (x86)"), it does not work completely under Windows 7. If I use task manager to turn on UAC Virtualization, it saves its config just fine, but of course it then can't load that config.
I do not want to set it to run as administrator, as it does not need those privileges. I want to set it to run with UAC Virtualization enabled.
I found a suggestion that I put some magic in the registry at HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags. For completeness I also put it in Wow6432Node, but neither had any effect.
File system is virtualized in certain scenarios, so is your question how to still turn it on when your application does not qualify? It is unlikely possible, MSDN:
Virtualization is not in option in the following scenarios:
Virtualization does not apply to applications that are elevated and run with a full administrative access token.
Virtualization supports only 32-bit applications. Non-elevated 64-bit applications simply receive an access denied message when they
attempt to acquire a handle (a unique identifier) to a Windows object.
Native Windows 64-bit applications are required to be compatible with
UAC and to write data into the correct locations.
Virtualization is disabled for an application if the application includes an application manifest with a requested execution level
attribute.
this may come way too late now, but I am the author of the suggestion you found to activate UAC virtualization, and there was a mistake in my post. The registry keys to modify are the following:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
(notice the "Layers" appended)
so a full example would be:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="RUNASINVOKER"
note that multiple parameters must be separated with space character.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="WINXPSP3 RUNASINVOKER"
--
I'm sincerely sorry that you lost a fair amount of time because of my mistake.
And by the way, let me express my disagreement with Ian Boyd's post. There are places where write privileges should not be granted to everyone, such as this one, since it breaks the base security rule of "System-wide writes should be authorised to privileged principals only". Program Files is a system-wide place, not a per-user one.
All rules have exceptions of course, but in the present case, one could imagine a maliciously crafted configuration file making the program exec an arbitrary command as the user running it. On a lighter side, one could imagine a "mistake delete" by another user, which would make the app fail. Back on the heavier side, application executables in Program Files are often run by the admin, sooner or later. Even if you don't want to, uninstalling programs very often run uninstall executables that are in Program Files. Maybe the uninstall procedure will use that config file which could have consequences if it's maliciously crafted.
Of course you may say, this sounds paranoid somehow, agreed. I did modify some NTFS ACLs in Program Files at the times of Win XP and was able to sleep after that, but why take the slightest risk when the tools are available ?
I found one not very well cited condition where UAC Virtualization does NOT work: when the file in Program Files is maked as read-only.
That is, suppose the file C:\Program Files\<whatever>\config.ini is marked as read-only. When the application try to change it, UAC Virtualization will return an access denied error instead of reparsing it to %LOCALAPPDATA%\VirtualStore\<whatever>\config.ini.
Although I did not found this documented, this behavior is probably done by design, since it makes some sense.
The solution is simple: assure that all files that are supposed to be modified by the application are not read-only (or just unflag all files, since the user will not be able to change them anyway).
You have an application, and you want users to be able to modify registry keys or files in locations that by default only Administrators can modify.
If you were running Windows 2000, or Windows XP, or Windows Vista, or Windows 7, or Windows 8, the solution is the same:
grant appropriate permissions to those locations
For example, if your program needs to modify files in:
C:\Program Files\Blizzard\World of Warcraft
Then the correct action is to change permissions on the World of Warcraft folder. This is, in fact, a shim that Microsoft applied to World of Warcraft. (On next run it granted Everyone Full Control to the folder - how else can WoW update itself no matter what user is logged in.)
If you want users to be able to modify files in a location: you have to grant them permission. If you were a standard user trying to run WoW on Windows XP you will get the same problem - and need to apply the same solution.
Your application is writing its configuration to:
C:\Program Files (x86)\Hyperion Pro\preferences.ini
then you, in fact do want to grant Users Full Control to that file:
So your:
application is not set to run as an Administrator
users cannot modify the executable
users can modify Configuration.ini
Granting permissions is not a bad thing; it's how you administer your server.
There are two solutions:
Install to C:\ProgramData\Contoso\Preferences.ini and ACL it at install time
Install to C:\Program Files\Contoso\Preferences.ini and ACL it at install time
And if you look at the guidance of the AppCompat guy at Microsoft:
Where Should I Write Program Data Instead of Program Files?
A common application code update is this: “my application used to write files to program files. It felt like as good a place to put it as any other. It had my application’s name on it already, and because my users were admins, it worked fine. But now I see that this may not be as great a place to stick things as I once thought, because with UAC even Administrators run with standard user-like privileges most of the time. So, where should I put my files instead?”
FOLDERID_ProgramData
The user would never want to browse here in Explorer, and settings changed here should affect every user on the machine. The default location is %systemdrive%ProgramData, which is a hidden folder, on an installation of Windows Vista. You’ll want to create your directory and set the ACLs you need at install time.
So you have two solutions:
create your file at install time, and ACL it so that all users can modify it at runtime
create your file at install time, and ACL it so that all users can modify it at runtime
The only difference is semantic. The Program Files folder is mean for program files. You don't want to store data here.
And it's not because Diego Queiroz has any insight about security.
It's because it's where just the programs go.
Sometimes machines are imaged with the same Program Files over and over. You don't want per-machine data in your image. That data belongs in ProgramData.
And it's not a security issue.
Some people have to learn where the security boundary is.
there are quite some good points in those other answers.
actually i have upvoted all of those.
so let's all combine them together and add some more aspect ...
the OP mentions some "legacy application from the old days".
so we can assume it is x86 (32bit) and also does not include any manifest (and in particular does not specify any "requestedExecutionLevel").
--
Roman R. has good points in his answer regarding x64 and manifest file:
https://stackoverflow.com/a/8853363/1468842
but all those conditions don't seem to apply in this case.
NovHak outlines some AppCompatFlags with RUNASIVOKER in his answer:
https://stackoverflow.com/a/25903006/1468842
Diego Queiroz adds intersting aspect regarding the read-only flag in his answer:
https://stackoverflow.com/a/42934048/1468842
Ian Boyd states that probably you don't even should go for that "virtualization", but instead set according ACL on those files of interest (such as "config.ini"):
https://stackoverflow.com/a/12940213/1468842
and here comes the addtional / new aspect:
one can set a policy to disable all virtualization - system-wide:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"EnableVirtualization"=dword:00000000
actually i'm enforcing this policy on each and every system that i own.
because otherwise it will lead to confusing behaviour on multi-user environments.
where UserA applies some changes and everything goes fine.
but then UnserB does not get the changes done by UserA.
in case some old crappy software fails then it should "fail"!
and not claim that everything went "fine".
IMHO this "Virtualization" thing was the worst design decision by microsoft, ever.
so maybe the system has this policy enabled and that's why virtualization doesn't work for you?
--
so probably the ultimate checklist would be:
is the application x86 or x64?
does the exe have a manifest (including the requestedExecutionLevel)?
have you checked the read-only attribute (e.g. of those INI files)?
is there a policy to force the EnableVirtualization to 0?
have you tried the AppCompatFlags with RUNASIVOKER?
or simply go for ACL instead of virtualization
--
in the end we are discussing how to get on old legacy application to run.
by using whatever workarounds and hacks we can think of.
this should probably better discussed on either superuser or serverfault.
at stackoverflow (targeted for programmers) we all know: it's about time to get all of our own programs compatible with UAC concept and how to implement things the "right" way - the "microsoft" way :)
As silverlight do not have access to local system files, we cannot perform any action on such files like to copy, move, delete, open ect.
In my case i want to get the path of file(s) located on local System, but getting some security exception. Please suggest some possible way to get access to the Local File System.
Thanks in Advance!!
To read a file from the filesystem in Silverlight, you can't use the pathname of the file. If you're not running out-of-browser with elevated trust, then you're prohibited from accessing this information for security reasons.
However, the FileInfo objects obtained from an OpenFileDialog have a OpenRead() method, which returns a Stream that reads the data from that file. From reading your comment, this appears to be all you need, so I suspect that you don't actually need the paths of files on the user's local system at all.
I gave a similar answer to another question about uploading files in Silverlight a few months ago.
If you're not running out-of-browser with elevated trust, then you're prohibited from accessing this information for security reasons.
http://social.msdn.microsoft.com/Forums/silverlight/en-US/da778e7c-e790-4bb2-92b8-cea815789d22/silverlight-4-local-filesystem-access?forum=silverlightnet
These tasks are not possible in Silverlight 4 without using Out-of-Browser with Elevated Trust.
In Silverlight 5 its possible after jumping through a few hoops to get an inbrowser app to have elevated trust.
Here is the situation. The company I work for builds this piece of software in c that can make a Windows computer act a bit like a TV. Essentially, our piece of software is meant to be played full screen and content is displayed from the internet without the user having to ever touch the computer again.
The problem is that once in a while, the system brings up pop-ups like "Your Windows system is ready for an upgrade." or "Please renew your Norton subscription" etc. which the user has to periodically and manually remove.
Is there a way to display content full screen without being bothered by those warnings?
Yah, whether or not the development community agrees, Microsoft has several standards for when and why it might be acceptable to have exclusive use of the monitor.
The most official strategy is to use DirectX in exclusive mode. This is what games do, what windows media player does in full screen video with hardware acceleration enabled, etc... If your application is multimedia intensive (as suggested by TV like functionality), you should probably be using DirectX too. Besides giving you the exclusive display access it will also increase your applications performance while lowering the CPU load (as it will overload graphics work to the video card when possible).
If DirectX is not an option, there are a great number of hacks available that seem to all behave differently between various generations of windows operating systems. So you might have to be prepared to implement several techniques to cover each OS you plan to support.
One technique is to set your application as the currently running screensaver. A screensaver if really just an EXE renamed to SCR with certain command line switches it should support. But you can write your own application to be such a screensaver and a little launcher stub that sets it as the screensaver and launches it. Upon exit the application should return the original screensaver settings (perhaps the launcher waits for the process to exit so that it returns the settings in both graceful exits and any unplanned process terminations ie: app crash). I'm not sure if this behavior is consistent across platforms though, you'll have to test it.
Preventing other applications from creating window handles is truly a hack in my opinion and pretty bad one that I wouldn't appreciate as a customer of such software.
A constant BringWindowToTop() call to keep you in front is better (it doesn't break other software) but still a little hack-ish.
Catch window creation messages with a global hook. This way you can close or hide unwanted windows before they become visible.
EDIT: If you definitely want to avoid hooks, then you can call a function periodically, which puts your window to the top of the z-stack.
You could disable system updates http://support.microsoft.com/kb/901037 and remove the norton malware.
You could also connect a second screen so that the bubbles appear in the the first monitor.
Or you rewrite it for linux or windows ce.
One final option is to install software that reconfigures your os into a kiosk http://shop.inteset.com/Products/9-securelockdown.aspx
If you don't need keyboard or mouse input, how about running your application as a screensaver?
A lot of thoses messages are trigged/managed by Windows Explorer.
Just replace it with your dummy c#/winform.
By changing the registry value
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
"Shell"="Explorer.exe"
You can specify virtually any exe as an alternative to explorer.exe
That's the way all windows based (embedded) system (ATM & co) do.
There's still few adjustment (disable services you dont need / dr watson & others), and of course, you'll want to keep a "restart explorer.exe" backdoor.
But that's a good start
I've become familiar with the new concept of "out of browser" web applications, supported in the recent Silverlight, JavaFX, Adobe AIR etc.
Listening recently to a podcast on the subject by Scott Hanselman, I've become aware that one of the purposes behind these new architectures is to allow for "desktop-application-feel". Also, I understand some (or all) of these allow for some offline access to a sandbox of resources. This really sounds as if these frameworks could be an alternative to "real" desktop applications, as long as the application does not require messing with the user's machine (i.e. access to peripherals, certain file IO, etc).
I have a very specific question. My application needs to run at start-up. Is it possible to do so using such a framework without requiring the user to download and run a certain executable?
For example, I could always direct the user to download a small EXE that will put a .lnk file in the start-up directory, but I want to avoid such a patch.
To summarize: is it possible to have an out-of-browser web application setup itself to run at start-up without requiring file download?
To further clarify, this question does not come from an "evil" place, but rather from trying to decide whether "out-of-browser" frameworks are indeed a proper alternative to a desktop application, for my specific requirements.
The BkMark example here shows how to start an application on startup using Adobe Air. So, yes it is possible.
So, here's the deal: web apps in general will have a security context around them, and by default won't have access to write to the filesystem (outside of a temp files), access the registry, etc.
One way is, as you said, have the user run something or configure it so the lnk is executed on startup.
Another way, and I think, more in line of what you want, is that the user can run the program himself, click some button in the application, and it's configured.
I know with Java you could do this, but the user has to allow full access to their system, because your app would need to change System configuration. Then you could just configure it (by writing a lnk to your WebStart JNLP in the Startup folder)
For Internet Exploder, Javascript apps do have write access to the disk.
For other (better-secured) browsers you will either need to have a download, or Adobe AIR.
Assuming you are building for Windows, launching an executable at startup can be done several ways.
For user session startup, you can achieve this either by putting a lnk file in the appropriate folder, or with a registry entry. For operating system startup, you can achieve this with a registry entry. There are several permutations:
run application once on boot (UI not allowed)
run application every boot (UI not allowed)
start service every boot according to policy set in registry
run application once on user session start
run application every user session
Since an out of browser application has UI I expect you mean run application every user session and in this case you may as well put an LNK file in the user's startup folder.
I just created a shortcut for an SL4 OOB application, and this was the Target of the shortcut:
"C:\Program Files (x86)\Microsoft Silverlight\sllauncher.exe" 2635882436.localhost
A search of my disk revealed that location 2635882436.localhost is a folder.
C:\Users\<mylogin>\AppData\LocalLow\Microsoft\Silverlight\OutOfBrowser\2635882436.localhost
I rather doubt an OOB app of any type could place a shortcut in the Startup folder unless you somehow obtained Full Trust.
I noticed that WPF application startup is sometimes pretty slow. Does anybody know if the the cause is the elements initialization or DLLs loading or something else?
The text below was extracted from this MSDN article on Improving WPF applications startup time (Edit: now merged into WPF Application Startup Time)
Application Startup Time
The amount of time that is required for a WPF application to start can vary greatly. This topic describes various techniques for reducing the perceived and actual startup time for a Windows Presentation Foundation (WPF) application.
Understanding Cold Startup and WarmStartup
Cold startup occurs when your application starts for the first time after a system reboot, or when you start your application, close it, and then start it again after a long period of time. When an application starts, if the required pages (code, static data, registry, etc) are not present in the Windows memory manager's standby list, page faults occur. Disk access is required to bring the pages into memory.
Warm startup occurs when most of the pages for the main common language runtime (CLR) components are already loaded in memory, which saves expensive disk access time. That is why a managed application starts faster when it runs a second time.
Implement a Splash Screen
In cases where there is a significant, unavoidable delay between starting an application and displaying the first UI, optimize the perceived startup time by using a splash screen. This approach displays an image almost immediately after the user starts the application. When the application is ready to display its first UI, the splash screen fades. Starting in the .NET Framework 3.5 SP1, you can use the SplashScreen class to implement a splash screen. For more information, see How to: Add a Splash Screen to a WPF Application.
You can also implement your own splash screen by using native Win32 graphics. Display your implementation before the Run method is called.
Analyze the Startup Code
Determine the reason for a slow cold startup. Disk I/O may be responsible, but this is not always the case. In general, you should minimize the use of external resources, such as network, Web services, or disk.
Before you test, verify that no other running applications or services use managed code or WPF code.
Start your WPF application immediately after a reboot, and determine how long it takes to display. If all subsequent launches of your application (warm startup) are much faster, your cold startup issue is most likely caused by I/O.
If your application's cold startup issue is not related to I/O, it is likely that your application performs some lengthy initialization or computation, waits for some event to complete, or requires a lot of JIT compilation at startup. The following sections describe some of these situations in more detail.
Optimize Module Loading
Use tools such as Process Explorer (Procexp.exe) and Tlist.exe to determine which modules your application loads. The command Tlist <pid> shows all the modules that are loaded by a process.
For example, if you are not connecting to the Web and you see that System.Web.dll is loaded, then there is a module in your application that references this assembly. Check to make sure that the reference is necessary.
If your application has multiple modules, merge them into a single module. This approach requires less CLR assembly-loading overhead. Fewer assemblies also mean that the CLR maintains less state.
Defer Initialization Operations
Consider postponing initialization code until after the main application window is rendered.
Be aware that initialization may be performed inside a class constructor, and if the initialization code references other classes, it can cause a cascading effect in which many class constructors are executed.
Avoid Application Configuration
Consider avoiding application configuration. For example, if an application has simple configuration requirements and has strict startup time goals, registry entries or a simple INI file may be a faster startup alternative.
Utilize the GAC
If an assembly is not installed in the Global Assembly Cache (GAC), there are delays caused by hash verification of strong-named assemblies and by Ngen image validation if a native image for that assembly is available on the computer. Strong-name verification is skipped for all assemblies installed in the GAC. For more information, see Gacutil.exe (Global Assembly Cache Tool).
Use Ngen.exe
Consider using the Native Image Generator (Ngen.exe) on your application. Using Ngen.exe means trading CPU consumption for more disk access because the native image generated by Ngen.exe is likely to be larger than the MSIL image.
To improve the warm startup time, you should always use Ngen.exe on your application, because this avoids the CPU cost of JIT compilation of the application code.
In some cold startup scenarios, using Ngen.exe can also be helpful. This is because the JIT compiler (mscorjit.dll) does not have to be loaded.
Having both Ngen and JIT modules can have the worst effect. This is because mscorjit.dll must be loaded, and when the JIT compiler works on your code, many pages in the Ngen images must be accessed when the JIT compiler reads the assemblies' metadata.
Ngen and ClickOnce
The way you plan to deploy your application can also make a difference in load time. ClickOnce application deployment does not support Ngen. If you decide to use Ngen.exe for your application, you will have to use another deployment mechanism, such as Windows Installer.
For more information, see Ngen.exe (Native Image Generator).
Rebasing and DLL Address Collisions
If you use Ngen.exe, be aware that rebasing can occur when the native images are loaded in memory. If a DLL is not loaded at its preferred base address because that address range is already allocated, the Windows loader will load it at another address, which can be a time-consuming operation.
You can use the Virtual Address Dump (Vadump.exe) tool to check if there are modules in which all the pages are private. If this is the case, the module may have been rebased to a different address. Therefore, its pages cannot be shared.
For more information about how to set the base address, see Ngen.exe (Native Image Generator).
Optimize Authenticode
Authenticode verification adds to the startup time. Authenticode-signed assemblies have to be verified with the certification authority (CA). This verification can be time consuming, because it can require connecting to the network several times to download current certificate revocation lists. It also makes sure that there is a full chain of valid certificates on the path to a trusted root. This can translate to several seconds of delay while the assembly is being loaded.
Consider installing the CA certificate on the client computer, or avoid using Authenticode when it is possible. If you know that your application does not need the publisher evidence, you do not have to pay the cost of signature verification.
Starting in .NET Framework 3.5, there is a configuration option that allows the Authenticode verification to be bypassed. To do this, add the following setting to the app.exe.config file:
<configuration>
<runtime>
<generatePublisherEvidence enabled="false"/>
</runtime>
</configuration>
Compare Performance on Windows Vista
The memory manager in Windows Vista has a technology called SuperFetch. SuperFetch analyzes memory usage patterns over time to determine the optimal memory content for a specific user. It works continuously to maintain that content at all times.
This approach differs from the pre-fetch technique used in Windows XP, which preloads data into memory without analyzing usage patterns. Over time, if the user uses your WPF application frequently on Windows Vista, the cold startup time of your application may improve.
Use AppDomains Efficiently
If possible, load assemblies into a domain-neutral code area to make sure that the native image, if one exists, is used in all AppDomains created in the application.
For the best performance, enforce efficient cross-domain communication by reducing cross-domain calls. When possible, use calls without arguments or with primitive type arguments.
Use the NeutralResourcesLanguage Attribute
Use the NeutralResourcesLanguageAttribute to specify the neutral culture for the ResourceManager. This approach avoids unsuccessful assembly lookups.
Use the BinaryFormatter Class for Serialization
If you must use serialization, use the BinaryFormatter class instead of the XmlSerializer class. The BinaryFormatter class is implemented in the Base Class Library (BCL) in the mscorlib.dll assembly. The XmlSerializer is implemented in the System.Xml.dll assembly, which might be an additional DLL to load.
If you must use the XmlSerializer class, you can achieve better performance if you pre-generate the serialization assembly.
Configure ClickOnce to Check for Updates After Startup
If your application uses ClickOnce, avoid network access on startup by configuring ClickOnce to check the deployment site for updates after the application starts.
If you use the XAML browser application (XBAP) model, keep in mind that ClickOnce checks the deployment site for updates even if the XBAP is already in the ClickOnce cache. For more information, see ClickOnce Security and Deployment.
Configure the PresentationFontCache Service to Start Automatically
The first WPF application to run after a reboot is the PresentationFontCache service. The service caches the system fonts, improves font access, and improves overall performance. There is an overhead in starting the service, and in some controlled environments, consider configuring the service to start automatically when the system reboots.
Set Data Binding Programmatically
Instead of using XAML to set the DataContext declaratively for the main window, consider setting it programmatically in the OnActivated method.
The most useful advice on fixing WPF startup performance I've ever seen was given in this other question: run "ngen update" in every framework folder.
It seems that Microsoft can't keep their ngen cache up-to-date, which results in your application pretty much recompiling half the .NET framework every single startup.
Hard to believe, but seems to be true.
The startup time of a WPF Application can be much faster if you use Framework 3.51 and not 3.5 or 3.0. The 3.51 is really an improvement.
This is an old thread, but I've ended up here several times while trying to fix a startup performance issue with WPF apps on my Win10 system, so I thought I'd state an answer which may help others - an answer that takes a horrible 5 second startup time for all WPF apps on this system down to just a few milliseconds. Remove the nVidia "3d Vision" driver. I have a GeForce GTX 650 card, and the "3d Vision" driver doesn't seem to offer anything useful, so removing it is no problem for me. The VisualStudio2015 performance analysis tool finally helped show that almost all the 5 second startup time was spent IDLE after a call through nvapi64.dll - the nVidia driver. Wow.
What helped me the most from the excellent article that Stuart links to was the XmlSerializer trick. That really shaved up quite a few seconds. Furthermore don't underestimate defragmenting your HD :-)