【问题标题】:check if exe is already running with same arguments c#检查exe是否已经使用相同的参数运行c#
【发布时间】:2019-11-27 18:54:24
【问题描述】:

如果 exe 已经在运行,我目前正在使用以下函数来停止我的 exe

public static bool IsAlreadyRunning()
{
    string strLoc = Assembly.GetExecutingAssembly().Location;
    FileSystemInfo fileInfo = new FileInfo(strLoc);
    string sExeName = fileInfo.Name;
    bool bCreatedNew;

    Mutex mutex = new Mutex(true, "Global\\" + sExeName, out bCreatedNew);
    if (bCreatedNew)
        mutex.ReleaseMutex();

    return !bCreatedNew;
}

但是我的 exe 可以使用不同的参数运行,所以只有当我的 exe 的另一个实例使用相同的参数运行时,我才需要停止该 exe。

那么有没有办法从上面的代码中获取参数或任何指针来完成这项工作?

【问题讨论】:

  • 仅当您使用参数生成互斥锁名称时。互斥锁只需要每个实例有一个唯一的名称。它不必包含可执行文件名称或参数本身,它可以是由它们生成的哈希。
  • 参数传递给Main方法,你可以检查一下
  • 好的干净的方法是将参数传递给方法。 quick&dirty 方法是使用 `Environment.CommandLine 获取整个命令行或使用 GetCommandLineArgs 获取参数
  • 只是一个建议,您可以将进程状态信息存储在二进制文件中。每当用户尝试运行新的 exe 时,您可以先检查此文件。如果有冲突,你可以通过它的 id 杀死前一个进程(它也可以存储在文档中),然后你可以运行新的。它不会阻止用户使用相同的参数运行相同的 exe,因为程序应该首先启动以检查文件,但至少您可以使用这种方法阻止其余进程。
  • @ycansener 这就是互斥锁的意义所在。即使进程崩溃,也必须删除锁定文件(您的建议)

标签: c# console-application


【解决方案1】:

您可以使用参数来生成互斥锁名称。互斥体只需要有一个唯一的名称就可以工作,它不必包含可执行文件的名称。

漂亮而干净的方法是将参数传递给方法。 quick&dirty 方法是使用Environment.CommandLine 获取整个命令行或使用GetCommandLineArgs 获取参数。

例如:

var args=String.Join("-",Environment.GetArguments());
var mutexName=$@"Global\{sExeName}-{args}";
var mutex = new Mutex(true, mutexName, out bCreatedNew);

一个更好的主意是先对参数进行散列,然后使用散列作为名称。使用哈希方法like the one in this answer,您可以从连接的字符串中计算出参数:

static string GetSha256Hash(string input)
{
    var hasher=SHA256.Create();
    byte[] data = hasher.ComputeHash(Encoding.UTF8.GetBytes(input));

    StringBuilder sBuilder = new StringBuilder();

    // Loop through each byte of the hashed data 
    // and format each one as a hexadecimal string.
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }

    // Return the hexadecimal string.
    return sBuilder.ToString();
}

...

var args=String.Join("-",Environment.GetArguments());
var argHash=GetSha256Hash(args);
var mutexName=$@"Global\{sExeName}-{argHash}";
var mutex = new Mutex(true, mutexName, out bCreatedNew);

【讨论】:

  • 当我通过运行两个 Visual Studio 实例检查它时它正在工作。但是当我从两个命令提示符调用 exe 时,它​​并没有识别出另一个 exe 实例以相同的参数运行。知道这里可能是什么问题吗?
  • @Pரதீப் 实际的互斥锁名称是什么?两个实例的名称是否相同?除此之外,代码与您开始使用的代码相同
  • 互斥体名称 - realtimefeed.exe-20191126 ||两个实例的名称是否相同 - 是的。我也尝试了哈希码版本,同样的问题,在 Visual Studio 中工作,但在调用 exe(取自 bin\release 文件夹)时不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-10
  • 2014-10-29
  • 2021-05-14
  • 1970-01-01
  • 2012-10-10
  • 2020-02-04
相关资源
最近更新 更多