c++程序只存在一个实例(exe)的方法

9 篇文章 1 订阅

最近项目开发过程中遇到了保证程序只有一个实例存在的需求,也就是只能存在一个exe。本人目前有两种实现的方法。

一、基于Qt的实现

基于Qt的实现是利用了Qt中的共享内存(QSharedMemory),第一个运行的exe创建一个共享内存,后续的程序如果能访问到此内存,就认为已有exe存在了。伪代码如下:

int main()
{
    //创建一个共享内存
    QSharedMemory sharedMemory;
    //设置共享内存的标识,这个标识是确定的
    sharedMemory.setKey(strPid);
    //尝试去attach由标识符指定的内存块,如果attach成功
    //说明这个内存段已经存在了,也就是说已经存在一个exe了那么就可以
    if (m_sharedMemory.attach())
    {
        m_bRunning = true;
        return;
    }
    else
    {
        m_bRunning = false;
        //运行到此,说明还不存在exe,创建一个大小为1的共享内存段
        if (!m_sharedMemory.create(1))
        {
            m_bRunning = true;
        }
    }
}

二、基于C++的实现

这里是针对windows平台,基于windows的接口实现。是根据名称去查找进程数量,然后进行处理。

//根据进程名称查找进程数量是否大于1
bool testOpenProcess::findProcessIdAccordName(const std::string& proName, QVector<DWORD>& proId)
{
    int i = 0;
    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(pe32);
    HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        i += 0;
    }
    BOOL bMore = ::Process32First(hProcessSnap, &pe32);
    while (bMore)
    {
        char ansi[512] = { 0 };
        WideCharToMultiByte(CP_ACP, 0, pe32.szExeFile, -1, ansi, sizeof(ansi), NULL, NULL);
        std::string path = ansi;

        std::string appName = proName;

        if (stricmp(appName.c_str(), ansi) == 0)
        {
            //printf("进程运行中");  
            i += 1;
            proId.push_back(pe32.th32ProcessID);
            printf("findProcessByName: find a same name exe:%s \n", path.c_str());
            //break;
        }
        //printf(" 进程名称:%s ;saved app name is %s\n", path.c_str(), appName.toStdString().c_str());
        bMore = ::Process32Next(hProcessSnap, &pe32);
    }
    ::CloseHandle(hProcessSnap);
    if (i > 1)
    {   //数量大于1,说明排除自身外,还存在一个同名进程,说明自己不是第一个  
        printf("findProcessByName : find a exe in task\n");
        return true;
    }
    else
    {
        //printf("findProcessByName : not find a exe in task\n");
        return false;
    }
}

int main()
{
    QVector<DWORD> appID;
    if (findProcessIdAccordName("testOpenProcess.exe", appID))
    {
        return;
    }
    //...后续操作
}

三、 linux平台下依赖qt接口实现判断,代码如下:

bool IsAlreadyRunning()   
{
    QString processName = qApp->applicationName();

    int account = 0;

    QString cmd = "ps -ef | awk '{print $2,$8,$9,$10,$11}'";
    QProcess p;
    p.start("bash", QStringList() << "-c" << cmd);
    if(!p.waitForFinished()){
        return true;
    }

    QString ret = p.readAllStandardOutput();
    QStringList lineList = ret.split("\n");

    for(int i = 1; i < lineList.size(); i++){

        QString PIDStr = lineList[i].split(" ")[0];
        QString programStr = lineList[i].split(PIDStr)[1].trimmed();
        QString programTmpPathNotPara = programStr.split(" ")[0];
        QStringList processTmpList = programTmpPathNotPara.split("/");
        QString programTmpName = processTmpList[processTmpList.size() - 1];

        if(programTmpName == processName){

            account++;
        }
        if(account >= 2){

            return true;
        }
    }

    return false;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值