- VAL.src.zip
- VAL
- Database
- packages
- EntityFramework.4.2.0.0
- lib
- net40
- EntityFramework.dll
- log4net.1.2.10
- lib
- 1.0
- log4net.dll
- 1.1
- log4net.dll
- 2.0
- log4net.dll
- log4net.1.2.11
- lib
- net10-full
- log4net.dll
- net11-full
- log4net.dll
- net20-cf
- log4net.dll
- net20-full
- log4net.dll
- net35-client
- log4net.dll
- net35-full
- log4net.dll
- net40-client
- log4net.dll
- net40-full
- log4net.dll
- Moq.4.0.10827
- lib
- NET35
- Moq.dll
- NET40
- Moq.dll
- Silverlight4
- Castle.Core.dll
- Moq.Silverlight.dll
- License.txt
- Moq.chm
- repositories.config
- structuremap.2.6.3
- lib
- StructureMap.dll
- READ-ME-First!.txt
- VAL.BusinessService
- VAL.ClientService
- VAL.Common
- VAL.Contracts
- VAL.Controls
- VAL.Data
- VAL.GUI
- VAL.Model
- VAL.Service
- VAL.sln
- VAL.Tests
- VAL.User.Documentation
- VAL.zip
- VisualApplicationLauncher
- Database
- Local.testsettings
- NRepo
- ProjectReferences
- EFCachingProvider.dll
- EFCachingProvider.Web.dll
- EFProviderWrapperToolkit.dll
- EFTracingProvider.dll
- log4net.dll
- StructureMap.dll
- READ-ME-First!.txt
- TraceAndTestImpact.testsettings
- VAL.BusinessService
- VAL.Common
- VAL.Contracts
- VAL.Controls
- VAL.Data
- VAL.GUI
- VAL.Model
- VAL.Service
- VAL.sln
- VAL.Tests
- VAL.User.Documentation
- VAL.vsmdi
|
namespace VAL.Common
{
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
/// <summary>
/// SingleProgamInstance uses a mutex synchronization
/// object to ensure that only one copy of process is running
/// at a particular time. It also allows for UI identification
/// of the intial process by bringing that window to the foreground.
/// </summary>
public class SingleProgramInstance : IDisposable
{
#region Win32 Declarations
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd,int nCmdShow);
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
private const int SW_RESTORE = 9;
#endregion
//private members
private Mutex _processSync;
private bool _owned = false;
/// <summary>
/// Default construct. Creates a mutex over the currently executing
/// assembly.
/// </summary>
/// <remarks>
/// DO NOT use this in a thin-client environment, as this will only allow
/// a single instance for the entire server, rather than on a per-user
/// basis
/// </remarks>
public SingleProgramInstance()
{
//Initialize a named mutex and attempt to
// get ownership immediately
_processSync = new Mutex(
true, // desire intial ownership
@"Local\" + Assembly.GetExecutingAssembly().GetName().Name,
out _owned);
}
/// <summary>
/// Construct that allow you to pass in the identifier for
/// your mutex
/// </summary>
/// <param name="identifier"></param>
public SingleProgramInstance(string identifier)
{
//Initialize a named mutex and attempt to
// get ownership immediately.
//Use an addtional identifier to lower
// our chances of another process creating
// a mutex with the same name.
_processSync = new Mutex(
true, // desire intial ownership
identifier,
out _owned);
}
/// <summary>
/// Finaliser for the class. This should have been accomplished using Dispose()
/// </summary>
~SingleProgramInstance()
{
//Release mutex (if necessary)
Release();
}
/// <summary>
/// Read only. Returns true if the application is the only running instance
/// </summary>
public bool IsSingleInstance
{
//If we don't own the mutex than
// we are not the first instance.
get {return _owned;}
}
/// <summary>
/// Method to place focus on the other instance, if one exists
/// </summary>
public void RaiseOtherProcess()
{
Process proc = Process.GetCurrentProcess();
// Using Process.ProcessName does not function properly when
// the actual name exceeds 15 characters. Using the assembly
// name takes care of this quirk and is more accruate than
// other work arounds.
string assemblyName =
Assembly.GetExecutingAssembly().GetName().Name;
foreach (Process otherProc in
Process.GetProcessesByName(assemblyName))
{
//ignore "this" process
if (proc.Id != otherProc.Id)
{
// Found a "same named process".
// Assume it is the one we want brought to the foreground.
// Use the Win32 API to bring it to the foreground.
IntPtr hWnd = otherProc.MainWindowHandle;
if (IsIconic(hWnd))
{
ShowWindowAsync(hWnd,SW_RESTORE);
}
SetForegroundWindow(hWnd);
break;
}
}
}
/// <summary>
/// Releases the resources in this classes finaliser, if Dispose has
/// not been called
/// </summary>
private void Release()
{
if (_owned)
{
//If we own the mutex than release it so that
// other "same" processes can now start.
try
{
_processSync.ReleaseMutex();
}
finally
{
_owned = false;
}
}
}
#region Implementation of IDisposable
/// <summary>
/// Dispose of the objects resources
/// </summary>
public void Dispose()
{
//release mutex (if necessary) and notify
// the garbage collector to ignore the destructor
Release();
GC.SuppressFinalize(this);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.