http://www.webasp.net/article/28/27714.htm
请先看看这个里的解决方案,我选择了标识标量来解决
问题原以为已经解决了,但是问题又出来了,如果程序出错,或者客户使用任务管理器把这个进程给结束掉了,程序就不能再启动了。有没有什么好的解决方案呢?
以下是代码:
 #region 标识变量
        private static string runFlagFullname = null;
        public static bool InitRunFlag()
        {
            if (File.Exists(RunFlag))
            {
                return false;
            }
            using (FileStream fs = new FileStream(RunFlag, FileMode.Create))
            {
            }
            return true;
        }
        public static void DisposeRunFlag()
        {
            if (File.Exists(RunFlag))
            {
                File.Delete(RunFlag);
            }
        }
        public static string RunFlag
        {
            get
            {
                if (runFlagFullname == null)
                {
                    string assemblyFullName = Assembly.GetEntryAssembly().FullName;
                    string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
                    runFlagFullname = Path.Combine(path, assemblyFullName);
                }
                return runFlagFullname;
            }
            set
            {
                runFlagFullname = value;
            }
        }
        #endregion
调用
static void Main()
        {
            if (SingleInstance.InitRunFlag())
            {                
                StartSystem();
                SingleInstance.DisposeRunFlag();
            }
            else
            {
                MessageBox.Show("程序已经运行!");
            }    
        }

解决方案 »

  1.   

    把这个flag的改变写到,主要功能的运行结束处,别写在程序的启动处
      

  2.   

    process來做,啟動時先查內存中有沒有這個進程,有就激活(最大化), 沒有就啟動。請參看msdn中關於process的相關用法。
      

  3.   

    要读写一个文件 显然是压根不用考虑的一个办法
    为什么呢?怕资源问题,显然这点资料太小了根本不是问题,看看http://www.webasp.net/article/28/27714.htm
    这个里的测试再说
      

  4.   

    这个flag写哪都不行 若是断电再次重新启动怎么办? flag就会一直存在 
    只有动态查找才是好点的做法
      

  5.   

    process來做,啟動時先查內存中有沒有這個進程,有就激活(最大化), 沒有就啟動。請參看msdn中關於process的相關用法。有问题,如果客户复制到另外的地方,他还不是可以运行多个了。我原来就是用process来做的,这个解决方法不好,还不如用进程互斥呢?
      

  6.   

    我认为初学者的意思是在一台机器上不能运行程序的多个实例 我也是这么想的
    如果程序只能运行一次 干脆在运行完毕的时候删除自己好了(可以参照vcbear的例子)就你的想法来说,无论你的程序怎么写的,只要你给我了,我大可以先复制到别的机器上然后再运行
    我就不信你能控制我只运行一次
      

  7.   

    用Mutex,取个乱点的名字,不可能和别的重复!
      

  8.   

    //看这是你要的不?
    //使用时在 main调用//判断是否已有实例存在
    CHandleRunningPro HandleRunning = new CHandleRunningPro();
    try
    {
    if(!HandleRunning.HandleRunningInstance())
    {
    //运行你的程序。
    }
    }
    catch()
    {
    }//////////////////////////////////////////////////////
    using System;
    using System.Text.RegularExpressions;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    namespace HandleRunningProcess
    {
    /// <summary>
    /// 判断是否已经有实例在运行的类
    /// </summary>
    public class CHandleRunningPro
    {
    /// <summary>
    /// const int, ShowWindowAsync 使用时的参数,让窗体正常显示确保没有隐藏和最小化。
    /// </summary>
    private const int WS_SHOWNORMAL = 1;  /// <summary>
    /// 功能:遍历所有运行的例程,判断是否已经有相同名字的例程。       
    /// 实现:遍历所有运行的例程,如果有与自己名字相同的比较 ID 是否相同。
    ///       如果ID不同说明已经有实例在运行,则把该实例返回。
    ///       如果没有则返回 null
    /// </summary>
    /// <returns>有相同名字的例程返回其 process,否则返回null</returns>
    private Process GetRunningInstance()
    {
    Process current = Process.GetCurrentProcess();
    Process[] processes = Process.GetProcessesByName (current.ProcessName); //遍历正在有相同名字运行的例程
    foreach (Process process in processes)
    {
    //忽略现有的例程
    if (process.Id != current.Id)
    {
    return process;
    }
    } //没有其它的例程,返回Null
    return null;
    } //接下来调用两个WinAPI,其功能将在包装方法中描述, 
    [DllImport("User32.dll")] 
    private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); 
    [DllImport("User32.dll")] 
    private static extern bool SetForegroundWindow(IntPtr hWnd); 
    //以上的方法声明为私有,对其进一步包装,
    /// <summary>
    /// 功能:HandleRunningInstance静态方法为获取应用程序句柄,设置应用程序为前台运行,并返回bool值。      
    /// 实现:确保窗口没有被最小化或最大化。
    ///       设置为前台显示。
    /// </summary>
    /// <param name="instance">准备设置成前台运行的程序</param>
    /// <returns></returns>
    private bool HandleRunningInstance(Process instance) 

    //确保窗口没有被最小化或最大化 
    ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); 
    //设置为foreground window 
    return SetForegroundWindow(instance.MainWindowHandle); 
    }  /// <summary>
    /// 功能:查找相同名字的进程,有则前台显示,无则返回 false
    /// 实现:1 查找相同名字的进程。
    ///       2 有相同名字的进程,将其前台显示,返回 true
    ///       3 无相同名字,返回 false
    /// </summary>
    /// <returns>有相同名字 true, 无相同名字 false</returns>
    public bool HandleRunningInstance() 

    Process p = GetRunningInstance(); 
    if (p != null) 

    HandleRunningInstance(p); 
    return true; 

    return false; 

    }
    }
      

  9.   

    捕捉窗体的标题,以前在DELPHI做过
      

  10.   

    static void Main()
    {
      bool createdNew;
      System.Threading.Mutex mutex = new System.Threading.Mutex(true, "myApplicationMutexName", out createdNew);
      //不是新建的Mutex,则表示已经运行过
      if (!createdNew)
      {
        System.Windows.Forms.MessageBox.Show("程序已经运行,不要再执行了!");
        return;
      }  Application.Run(new FormMain());  //释放
      mutex.ReleaseMutex();
    }
      

  11.   

    楼主的需求不是只运行一个实例,运行一个实例在我的博客上有三种方法
    你自己写一个自杀程序就行了,网上VC代码很多,我以前也用BCB写过,不难的
    我现在用C#改写遇到了个问题,就是用
    CreateFile(ff, 0, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_DELETE_ON_CLOSE,NULL);程序退出时系统无法删除ff指定的文件