zoukankan      html  css  js  c++  java
  • c# 实现一个程序仅能运行一个副本

    恩,也就是说一个程序如果已经运行了,则不能再运行这个程序的一个副本.如果运行副本,则程序自动关闭,并把已经运行的程序的窗口打开.

    开始使用mutex来实现的,但是这个我只能实现到判断副本的运行,不能把已经运行的窗口自动打开,后来使用其它方式实现的。

    使用一个文件做一个标志,标志着一个副本在运行,并且一至不停的检测这个标志,代码:

     using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.IO;
    using System.Threading;

    namespace WindowsApplication8
    {
     static class Program
     {
      ///


      /// 应用程序的主入口点。
      ///
      [STAThread]
      static void Main()
      {
       if (File.Exists(Application.StartupPath + "/mutex.tmp"))
       {
        File.Delete(Application.StartupPath + "/mutex.tmp");
        Thread.Sleep(1000);
        if (File.Exists(Application.StartupPath + "/mutex.tmp"))
         return;

       }

       Application.EnableVisualStyles();
       Application.SetCompatibleTextRenderingDefault(false);
       Application.Run(new Form1());
      }
     }
    }

     using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.IO;
    using System.Windows.Forms;

    namespace WindowsApplication8
    {
     public partial class Form1 : Form
     {
      public Form1()
      {
       InitializeComponent();
      }

      private void Form1_Load(object sender, EventArgs e)
      {
       this.timer1.Start();
      }

      private void timer1_Tick(object sender, EventArgs e)
      {
       if (!File.Exists(Application.StartupPath + "/mutex.tmp"))
       {
        FileStream fs= File.Create(Application.StartupPath + "/mutex.tmp");
        fs.Close();

        this.WindowState = FormWindowState.Normal;
       }

      }
     }
    }

     虽然办法有些苯,但总归实现了.其它很多方法只能是先但进行运行,窗口没法自动出来,现在这个办法是我能想到的最简的地了.


    看CSDN中lovefootball的帖子,使用他介绍的:http://www.codeproject.com/csharp/cssingprocess.asp

    这个比我的实现方式要好,经过测试非常好用,代码如下:

     using System;
    using System.Collections.Generic;
    using System.Windows.Forms;

    namespace WindowsApplication9
    {
     static class Program
     {
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]
      static void Main()
      {
       using (SingleProgramInstance spi = new SingleProgramInstance("x5k6yz"))
       {
        if (spi.IsSingleInstance)
        {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new Form1());
        }
        else
        {
         spi.RaiseOtherProcess();
        }
       }

      }
     }
    }

     using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Reflection;

    namespace WindowsApplication9
    {
     //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 bring that window to the foreground.
     public class SingleProgramInstance : IDisposable
     {

      //Win32 API calls necesary to raise an unowned processs main window
      [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;

      //private members
      private Mutex _processSync;
      private bool _owned = false;
      
     
      public SingleProgramInstance()
      { 
       //Initialize a named mutex and attempt to
       // get ownership immediatly
       _processSync = new Mutex(
        true, // desire intial ownership
        Assembly.GetExecutingAssembly().GetName().Name,
        out _owned);
      }

      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
        Assembly.GetExecutingAssembly().GetName().Name + identifier,
        out _owned);
      }

      ~SingleProgramInstance()
      {
       //Release mutex (if necessary)
       //This should have been accomplished using Dispose()
       Release();
      }

      public bool IsSingleInstance
      {
       //If we don't own the mutex than
       // we are not the first instance.
       get {return _owned;}
      }

      public void RaiseOtherProcess()
      {
       Process proc = Process.GetCurrentProcess();
       // Using Process.ProcessName does not function properly when
       // the name exceeds 15 characters. Using the assembly name
       // takes care of this problem 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);
         return;
        }
       }
      }

      private void Release()
      {
       if (_owned)
       {
        //If we owne the mutex than release it so that
        // other "same" processes can now start.
        _processSync.ReleaseMutex();
        _owned = false;
       }
      }

     #region Implementation of IDisposable
      public void Dispose()
      {
       //release mutex (if necessary) and notify
       // the garbage collector to ignore the destructor
       Release();
       GC.SuppressFinalize(this);
      }
     #endregion
     }
    }

    这个代码就是使用mutex实现的,非常的不错。效率等方面应该比我那种简单的方式强很多,推荐使用。

  • 相关阅读:
    11.2hadoop监控:日志配置、堆栈跟踪、度量和JMX
    11.1.3hadoop工具dfsadmin、fsck、数据库扫描器、均衡器
    11.1.2hadoop 安全模式
    11.1.1namenode和datanode的数据结构和格式以及镜像fsimage和编辑日志edit
    10.5 hadoop集群基准评测程序测试
    10.4 hadoop安全性kerberos安全验证和委托令牌
    零基础学习python_生成器(49课)
    安全测试5_服务端的安全漏洞(SQL注入、命令注入、文件操作类)
    安全测试4_客户端的安全漏洞(XSS、CSRF、点击劫持、URL跳转)
    零基础学习python_魔法方法(41-48课)(迭代器)
  • 原文地址:https://www.cnblogs.com/jordan2009/p/1921620.html
Copyright © 2011-2022 走看看