Rick Glos Life in Portland, Oregon.

WPF Application Single Instance Detection - Only allow running your application once

14. June 2013 09:57 by Rick Glos in Programming

I have a requirement where I only want the application to be launched once.  If a subsequent launch of the application occurs, I want it to not pop-up a message to the user but to gracefully select the existing application that has already been launched, therebye preventing multiple launches of the same application.

The current application I’m targeting is a utility application (WoT Kit) I’ve written for World of Tanks that parses your battle results.  Part of the parsing process involves using an external 3rd parties site to convert the battle results from binary python in JSON.  The application uploads the binary file and gets back a string of JSON.  The guy running the website emailed me because he saw the same file getting uploaded in his logs.  Further investigation points to a user running the application more than once, most likely by accident as sometimes we get a lot of applications running.

So how is this done using a WPF application?  Further complicating this is that I’m using the Prism Patterns & Practices libraries for composite WPF applications.  I lean on this often for work related projects so this is useful in many scenarios.

Implement the Main method

First we need to take over how the application is launched.  In a WPF application, the entry point is generated for you.  If you select the option to view all files, you’ll see in your obj\$(Configuration) folder a App.g.cs file that contains the code that is the entry point.

6-14-2013 9-15-47 AM

   1:/// <summary>
   2:/// App
   3:/// </summary>
   4:public partial class App : System.Windows.Application {
   5:
   6:/// <summary>
   7:/// Application Entry Point.
   8:/// </summary>
   9:        [System.STAThreadAttribute()]
  10:        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
  11:        [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
  12:public static void Main() {
  13:            WoTBattleResultsKit.App app = new WoTBattleResultsKit.App();
  14:            app.Run();
  15:        }
  16:    }

Instead we want to be in control of this bit of code.  So add a class called Startup to your project and add a Main method and just copy+paste the internal stuff from the prior Main method.

   1:class Startup
   2:    {
   3:        [STAThread]
   4:static void Main()
   5:        {
   6:            WoTBattleResultsKit.App app = new WoTBattleResultsKit.App();
   7:            app.Run();
   8:        }
   9:    }

Change your project startup object to specifically use your class.

6-14-2013 9-07-52 AM

When you F5, your application should launch just as it did previously.

Add a Activate method to your existing Application class

Next we want to open our existing class that contains the inheritance of our Application class.  For most people, and Prism users as well, this will be your App.xaml.cs file.

6-14-2013 9-38-06 AM

Crack that open and add the Activate method.

6-14-2013 9-39-24 AM

Codez:

   1:public void Activate()
   2:        {
   3: // Reactivate application's main window
   4: this.MainWindow.Activate();
   5:        }

Add the SingleInstanceManager class to encapsulate handling the single instance logic

I put this code in the Startup.cs file.  Here we are going to add a class to handle the logic for when the application is launched and when it is launched again.  We are also going to rely on the WIndowsFormsApplicationBase which is inside of Microsoft.VisualBasic library.

Here’s where you go “ermhagerd you can’t do this!  VB in my C#.”  Well get over it.  That library is in the .NET Framework, you’re not requiring the user a separate download.  Who cares if it’s VisualBasic or System.ConfigurationUtils.  It’s also the recommended implementation from MSDN (Single Instance Detection Sample).  I’ve seen other solutions using Mutex, etc – but seems unnecessarily complex – each his own.  Read all the glorious arguments for and against on StackOverflow.

Here’s the code for the entire Startup.cs with the modified Main method to use the SingleInstanceManger and the Main methods code moved inside the SingleInstanceManager.OnStartup.

   1:class Startup
   2:    {
   3:        [STAThread]
   4:static void Main(string[] args)
   5:        {
   6:            SingleInstanceManager manager = new SingleInstanceManager();
   7:            manager.Run(args);
   8:        }
   9:    }
  10: 
  11:public class SingleInstanceManager : WindowsFormsApplicationBase
  12:    {
  13:        App app;
  14: 
  15:public SingleInstanceManager()
  16:        {
  17: this.IsSingleInstance = true;
  18:        }
  19: 
  20:protected override bool OnStartup(StartupEventArgs eventArgs)
  21:        {
  22: // First time app is launched
  23:            app = new WoTBattleResultsKit.App();
  24:            app.Run();
  25: return false;
  26:        }
  27: 
  28:protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
  29:        {
  30: // Subsequent launches
  31: base.OnStartupNextInstance(eventArgs);
  32:            app.Activate();
  33:        }
  34:    }

From here you are good to go.

I’ll be using the technique for future applications and using it to update some existing applications that do this currently but do things like searching thru the processes running on the machine and throwing pop-up windows, like “You already have one of this application running" as this technique is much more user friendly.

Visual Studio 2012 theme, caps and pending changes window

1. May 2013 11:19 by Rick Glos in Programming

I’ve been living in Visual Studio 2012 for a couple weeks now, finally making the switch from Visual Studio 2010 to Visual Studio 2012 for most of my work and doing the usual stuff of upgrading projects and tools, etc.

Many people have complained about the UI and I’m not normally one to customize but it has been hard.  I find myself having having mental hiccups figuring out which tab is active or why can’t I see xyz in the pending changes window?  My co-worker and I were discussing and came across some good links I wanted to document.

  1. Customizing the theme.

    A really good extension called Color Theme Editor. A good video on how it works.

  2. Getting rid of the all caps.

    It involves the registry, but thankfully there's a way to remove those capitals.

  3. Getting the old pending changes window back.

    I think Pending Changes merits its own window, not being buried in the Team Explorer window.

VS2012 unit tests fail when using Microsoft.SqlServer.Smo

24. April 2013 06:30 by Rick Glos in Programming

I’ve got a bunch of unit tests that were in an existing VS2010 project that worked great.  They had an AssemblyInitialize method that dropped and recreated the database and used Microsoft.SqlServer.Smo to run scripts.

When I upgraded this solution to VS2012 the unit tests would no longer execute and I was receiving the following error:

System.IO.FileLoadException: Mixed mode assembly is built against version ‘v2.0.50727’ of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.. Aborting test execution.

I can’t very well change how Microsoft.SqlServer.Smo is compiled.

Googling around I didn’t find much but eventually ran across a comment buried in StackOverflow question about hand editing the VS2012 test runner.

The solution is to open the config file at C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.executionengine.x86.exe.config and add the following:

<startup useLegacyV2RuntimeActivationPolicy="true"><supportedRuntime version="v4.0"/></startup>

Note that I had to restart VS2012 to unload the exe and reload it.  You can see it running as a child process of VS2012 in Process Explorer.

4-24-2013 6-25-49 AM

Hope that helps someone else.

Unable to manage networking component. Operating system corruption bay be preventing installation.

15. April 2013 13:13 by Rick Glos in

In attempting to install some VPN software to connect to a client I received a ambiguous message from the installer.

Unable to manage networking component. Operating system corruption bay be preventing installation.

4-15-2013 9-53-44 AM

Some googling turned up a good post about Windows 7 being limited to 14 network filter drivers but is set by default to only 8 (post) along with a link to technet forums (post).

Although the post was on Cisco forums, and I was installing some SonicWALL software, I assumed SonicWALL was just a re-branding of the Cisco installer.  In addition I have a number of what I think would be ‘network filter driver’ software like Windows Virtual PC’s, VirtualBox, Network Monitor, and other client VPN connection tools.

To increase the network filters to allow the software into install, modify your registry key at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Network\MaxNumFilters and change the value from 8 to 14.

This did not require a reboot.

Using ASP.NET Web API to disable Windows applications

27. February 2013 14:10 by Rick Glos in

Had an interesting problem to solve where sometimes at a client we need to disable applications during maintenance upgrades, overnight failures, etc. that would cause the application to either crash or show data that isn’t quite right, thereby confusing the users.  With a web application I’ve been using the App_Offline.htm trick for some time.  However what if it’s a windows application?

2-26-2013 4-48-01 AM

To solve this, I added a block of code that gets called during startup in these apps to determine if the application should be disabled.  Then someone, can use the web application to set a bit that the app is disabled and optionally add a reason that will get presented to the user.

In the windows applications I’m coding these days I’ve been using Prism heavily.  The best spot I could identify to place this method is in the InitializeShell before the user gets to see any UI and in the case of Prism, if the shell loads, it will start loading any modules you have registered with a region.  There, we call a method to go to the Web API and get back information.

   1:/// <summary>
   2:/// Initializes the shell.
   3:/// </summary>
   4:/// <remarks>
   5:/// The base implementation ensures the shell is composed in the container.
   6:/// </remarks>
   7:protected override void InitializeShell()
   8:{
   9:// Do not allow the application to launch if instructed not to do so
  10:    CheckToSeeIfApplicationIsDisabled();
  11: 
  12:base.InitializeShell();
  13: 
  14:    Application.Current.MainWindow = (Window)this.Shell;
  15:    Application.Current.MainWindow.Show();
  16:}

In the CheckToSeeIfApplicationIsDisabled method I call a service called InfrastructureService which handles the calling of the ASP.NET Web API.  In our case, we’ll need the application name, environment (test, production, beta, etc) and the url.

   1:private void CheckToSeeIfApplicationIsDisabled()
   2:{
   3:// Use whatever services necessary to get the infrastructure url, application name and environment - this is application dependent
   4:    var applicationSettingsService = Container.Resolve<IApplicationSettingsService>();
   5:    var assemblyInformationService = Container.Resolve<IAssemblyInformationService>();
   6:string infrastructureUrl = applicationSettingsService.InfrastructureUrl;
   7:string applicationName = assemblyInformationService.ProductName;
   8:string environment = applicationSettingsService.Environment.ToString();
   9: 
  10:// Use the InfrastructureService to check to see if the application is disabled
  11:    var infrastructureService = new InfrastructureService(infrastructureUrl);
  12:    var serverApplicationMetadata = infrastructureService.GetMetadata(applicationName, environment);
  13:if (serverApplicationMetadata != null && serverApplicationMetadata.Disabled)
  14:    {
  15:        var caption = string.Format("{0} - {1} - Application Disabled", applicationName, environment);
  16:        MessageBox.Show(serverApplicationMetadata.DisabledReason, caption, MessageBoxButton.OK, MessageBoxImage.Information);
  17:        Application.Current.Shutdown();
  18:    }
  19:}

Lastly we do the part where we call the service and get back data.  The data that we get back is in JSON format but using the ReadAsAsync method we can have the JSON get deserialized into a typed object if we want.  What’s cool is you don’t have to define every bit of information in the JSON, only those properties you care about.  If you don’t want to do it that way, you can also just use JToken objects to parse the returned JSON and grab the values you need.

Note that because this is an intranet, I need to pass in credentials and so I’m using a HttpClientHandler and passing that into the HttpClient.  I have it swallowing exceptions as I don’t want the applications to fail to load if the server is down or some other strange exception is thrown.  We should circle back around and at least log the exception using the Exception Handling Application Block so it gets logged somewhere.

   1:/// <summary>
   2:/// An encapsultion of calling the web api to get application information, etc.
   3:/// </summary>
   4:/// <remarks>
   5:/// <para>
   6:/// When using this service, add the Web API Client Libraries package to your project.  To do this, 
   7:/// click 'Manage NuGet Packages for Solution...', select 'Online', type 'Microsoft.AspNet.WebApi.Client' 
   8:/// in the search box, select the package and click Install.
   9:/// </para>
  10:/// <para>
  11:/// We may want to put this in a library if it's used alot or across different languages so that apps can just reference an external library.
  12:/// </para>
  13:/// </remarks>
  14:public class InfrastructureService
  15:{
  16:private readonly string _infrastructureUrl;
  17: 
  18:/// <summary>
  19:/// Default constructor requires the url.
  20:/// </summary>
  21:/// <param name="infrastructureUrl">Url, Example: http://yourserver/beta/Infrastructure</param>
  22:public InfrastructureService(string infrastructureUrl)
  23:    {
  24:this._infrastructureUrl = infrastructureUrl;
  25:    }
  26: 
  27:/// <summary>
  28:/// Returns an object with infromation regarding this application from a central server.
  29:/// </summary>
  30:/// <param name="applicationName">The name of the application as it exists in [infrastructure].[application].</param>
  31:/// <param name="environment">Production, Beta</param>
  32:/// <returns></returns>
  33:/// <remarks>
  34:/// We may want to make the environment parameter an enum or leave it string so it's very flexible in case more environments are added.
  35:/// </remarks>
  36:public ApplicationMetadata GetMetadata(string applicationName, string environment)
  37:    {
  38:        ApplicationMetadata result = null;
  39: 
  40:try
  41:        {
  42: using (var handler = new HttpClientHandler() { UseDefaultCredentials = true })
  43:            {
  44: using (var client = new HttpClient(handler))
  45:                {
  46:                    client.BaseAddress = new Uri(_infrastructureUrl);
  47:                    var requestUri = string.Format("api/applications?environment={0}&name={1}", environment, applicationName);
  48:                    HttpResponseMessage response = client.GetAsync(requestUri).Result;// Blocking call!
  49: if (response.IsSuccessStatusCode)
  50:                    {
  51: // Example #1: transform into somthing typed
  52:                        var convertTask = response.Content.ReadAsAsync<ApplicationMetadata>();
  53:                        var convertTaskResult = convertTask.Result as ApplicationMetadata;
  54:                        result = convertTaskResult;
  55: 
  56: // Example #2: transform into something not-typed/dynamic (useful for peeking at all the JSON)
  57: //var taskResults = response.Content.ReadAsAsync<Newtonsoft.Json.Linq.JToken>();
  58: //var taskResult = taskResults.Result as Newtonsoft.Json.Linq.JObject;
  59: //foreach (var item in result)
  60: //{
  61: //    var jitem = item as JObject;
  62: //    var disabled = jitem["Disabled"];
  63: //    var disabledReason = jitem["DisabledReason"];
  64: //}
  65:                    }
  66:                }
  67:            } 
  68:        }
  69:catch (Exception)
  70:        {
  71: // TODO: Handle the exception by logging it or swallowing it.  Do not rethrow as we don't want the inability to communicate with infrastructure app to bring down the application.
  72:        }
  73: 
  74:return result;
  75:    }
  76: 
  77:public class ApplicationMetadata
  78:    {
  79:public int ID { get; set; }
  80:public string Name { get; set; }
  81:public bool Disabled { get; set; }
  82:public string DisabledReason { get; set; }
  83:    }
  84:}

How to enable Silverlight debugging in web application if it somehow stops working

4. October 2010 09:03 by Rick Glos in

I’m posting this because I ran in circles for an hour trying to determine why I suddenly could not debug Silverlight code.

I had set a breakpoint, set the web application as the startup project, and yet it was skipping the breakpoint.

10-4-2010 8-48-30 AM

I tend to lean heavily on source control, and in our case, Team Foundation Server for determining, “what has changed”.  This was working in the past and I didn’t see any files checked out with any changes.

Turns out this setting is kept in your user specific project file.  I don’t remember unchecking this option.

Right click on your Web application project, not the Silverlight project and select Properties.  Then select the Web tab.  On the bottom of that page you’ll see the ‘Debuggers’ checkbox group.  Check Silverlight.

10-4-2010 8-40-26 AM

Apparently this setting is stored in your *.user configuration file for the project.  Here’s what was in the file before.

   1: <SilverlightDebugging>False</SilverlightDebugging>

And now after.  (Note this setting is updated when you close the solution – until then those settings are in memory – helpful to know if you check the box, hit save, and look at the file you will see no change as I did.  VS hasn’t persisted the value yet.)

   1: <SilverlightDebugging>True</SilverlightDebugging>

Now the breakpoint will be hit when we debug.

10-4-2010 8-55-51 AM

My guess is that there was some dialog that popped up and I automatically replied ‘Yes’ which unchecked it for me.  Doing me a favor yes?  Anyway, hope this helps.

Show output window during build in Visual Studio 2010

23. August 2010 08:07 by Rick Glos in

I was complaining to my co-worker the other day that my output window in Visual Studio 2010 was not showing during a build.  I usually hit Ctrl+Shift+B, and while I appreciate the minimalist UI, I like to see what it’s doing.  All I would see was the status bar text saying, “build started…” followed by, “build succeeded”, or in same cases, “build failed”.

image

When I was watching my co-worker, the output window popped up showing a log of the progress.  I think this is the default but I don’t recall changing my configuration.  I do normally take the output window and unpin it so it stays out of the way and off my screen while I’m coding.  Perhaps the act of doing this flips the option.  I don’t know.  What I’m after is when compiling, slide the window up from the bottom and show a log of what is compiling.

image

I poked around and found the option to turn this on or off and here it is for future reference.

Tools –> Options –> Projects and Solutions –> General –> Show Output window when build starts

image

How to run windows batch files from Visual Studio 2010 Solution Explorer

11. August 2010 11:35 by Rick Glos in

This is an update to running cmd files from Visual Studio 2005 and Visual Studio 2008 post I did a couple years ago.  You can use this technique to run windows command files with the .bat and .cmd extensions.

Just as previously, we need to create at least one, and optionally two, external tools.

One that terminates the window after executing.

Here’s the values for you to copy+paste and screenshot.

Field Value
TitleRun With Cmd
Command%ComSpec%
Arguments/C $(ItemPath)
Initial Directory$(ItemDir)

screenshot

One that leaves the command window open after executing.  Useful if you didn’t put a ‘pause’ in your command file or if you want to leave the cmd window open for additional commands.

Field Value
TitleRun With Cmd and Remain
Command%ComSpec%
Arguments/K $(ItemPath)
Initial Directory$(ItemDir)

screenshot

Now we should see our new external tools available on the Tools menu.

image

However, we’d like to right-click on the file and run the cmd file via Solution Explorer like so:

image

Customizing this context menu in Visual Studio 2010 is abit different from context menu customization in VS2005/2008.

Click Tools –> Customize… to launch the Customize Dialog.

From that dialog we want to select the ‘Context menu’ radio option and the ‘Project and Solution Context Menus | Item’ from the drop down.  I’m going to put the two commands right under ‘Open With…’.  You can certainly do whatever you wish.  Start this process by clicking ‘Add Command’ button on the same dialog.

So here’s a screenshot with that above paragraph in a picture instead of words:

image

When we click ‘Add Command’, the Add Command Dialog will open.  Select ‘Tools’ from the Catgories list box on the left and find your external command from the command list box on the right.  Your command will be named something like ‘External Command {Number}’ where {Number} is the number in your list from your External Tools dialog.

image

Clear as mud?  I’m going to use this to make sure I add External Command 3 and External Command 4 to the context menu.

image

Now the ‘Project and Solution Context Menus | Item’ context menu should look like this in the Customize Dialog.

image 

Close that dialog and check out your new menu items by right clicking on a file in Solution explorer.  You should see your new external commands.

image

For extra credit, you can go back into the Customize dialog and move your commands around into spot your like and alos create a Group around them.

image

 

The finished product looks like this.

image

Configuring Windows Server 2003 with ASP.NET 4.0 while supporting ASP.NET 2.0

10. August 2010 16:28 by Rick Glos in

Went through some interesting configurations today and wanted to document it.

Our client has a server, Windows Server 2003 SP2, in which we already have many ASP.NET 2.0 applications running, including some serving up Silverlight 3.0.  We needed to migrate one of our applications to ASP.NET 4.0 and Silverlight 4.  It was a little more involved than I would’ve thought.

Here’s the steps:

Install the .NET 4.0 Framework on the server.

This did not require a server reboot.  I have yet to have a reboot required when installing a .NET Framework version.  Perhaps I’ve been lucky so far.  This is important because you don’t want to disrupt folks using the resources on the box.

Create a separate App Pool for the web applications that are going to run under .NET 4.0.

From what I understand, you can’t have different web applications running under the same application pool.  Since this box has production and beta applications on it already, we need to create an app pool.  Nothing fancy.

Create the new virtual directory for the new application and assign it your new app pool

Nothing fancy here.  Use the properties dialog to create the application and assign the app pool.

image

Install the scriptmaps for ASP.NET 4.0 to the new web application.

If you don’t do this step and you try to run the application under 2.0 you will get error:

Unrecognized attribute 'targetFramework'

This is because the web.config is different now and contains a new attribute on the compilation element.

 image

If you try and set the ASP.NET version using the properties panel, you will get a warning that you are going to cause a restart of the entire W3SVC service therebye killing all the work anyone may be in the middle of using existing applications.

 image

Since we don’t want to disrupt currently running applications, we need to do this through the command line.

Open a cmd prompt and navigate to the v4 Framework directory: %WINDIR%\Microsoft.NET\Framework\v4.0.30319.  Once there, we can use the administration utility to change the application.

   1: aspnet_regiis.exe -s W3SVC/1/ROOT/SampleApp1

Here’s an example of the output when doing this against a test application.

image

Enable ASP.NET v4.0.30319 web service extension

If you try to hit the web application prior to this step you will receive ‘The page cannot be found’.

image

Enable the new version ASP.NET by using the Web Service Extensions node in IIS 6 and switching ASP.NET v4.0.30319 from Prohibited to Allowed.

image

Finished

From here you should be done and can now use your application right alongside older ones on the same web server.

Visual Studio 2008 locks in ASPX design view

3. August 2010 12:38 by Rick Glos in

Had a strange problem today that took a couple hours to resolve.

I originally experienced it when I tried to add a new Web Content Form, once I selected the master page, Visual Studio 2008 would lockup.  Anywhere I clicked would return a windows beep.  If I moved other applications over the window, only the tab that contained the new page would not get repainted.

8-3-2010 12-25-28 PM

I also experienced it when opening an ASPX file and clicking the design view tab Visual Studio 2008 would lock or freeze. 

8-3-2010 12-28-34 PM

I could only kill the devenv.exe process. 

A little searching turned up some strange results and I finally stumbled across a couple posts that seemed to be intelligent. (post 1 | post 2).

I regurgitating it here in case those go linkdead.

The gist is that the Office 2010 install somehow fubared some shared components.  Personally, I only experienced pain when I installed Visio 2010 and not the Office 2010 install I did a few months ago.

Run the Office 2007 Setup file located here:

C:\Program Files (x86)\Common Files\microsoft shared\OFFICE12\Office Setup Controller\Setup.exe

Now click ‘Repair’.

MSVSWAC

It ran a few minutes.  Run Visual Studio and fixed.