重命名后如何获得应用程序名称?

Som*_*ody 4 winapi

在应用程序运行时更改了可执行文件的名称后,两者GetModuleFileNameGetModuleFileNameEx使用PID都将返回原始文件名。

如何获得新的文件名,甚至检测到更改?理想情况下,我宁愿不使用FindFirstChangeNotification

Zhu*_* Ma 5

使用QueryFullProcessImageName。

我遇到了同样的问题,并尝试了GetModuleFileName,GetProcessImageFileName和QueryFullProcessImageName。最后一个可以工作。

这是我编写的一个简单演示。

#include <Windows.h>
#include <Psapi.h>
#include <stdio.h>

#pragma comment(lib, "Psapi.lib")

void OutputSelfpath()
{
    char szFile[MAX_PATH] = {0};
    GetModuleFileName(NULL, szFile, MAX_PATH);
    printf("GetModuleFileName:\n\r%s\n\n", szFile);

    memset(szFile, 0, MAX_PATH);

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
    if (!hProcess)
    {
        printf("OpenProcess failed!\n");
    }
    else
    {
        DWORD dwRet = GetProcessImageFileName(hProcess, szFile, MAX_PATH);
        if (dwRet)
        {
            printf("GetProcessImageFileName:\n\r%s\n\n", szFile);
        }
        else
        {
            printf("GetProcessImageFileName failed!\n");
        }

        memset(szFile, 0, MAX_PATH);
        DWORD dwSize = MAX_PATH;
        if (QueryFullProcessImageName(hProcess, 0, szFile, &dwSize))
        {
            printf("QueryFullProcessImageName:\n\r%s\n\n", szFile);
        }
        else
        {
            printf("QueryFullProcessImageName failed\n", szFile);
        }
    }
}

int main()
{
    const char* pszFile = "ConsoleTest.exe";
    const char* pszNewFile = "ConsoleTest_bak.exe";
    remove(pszNewFile);

    OutputSelfpath();

    int nRet = rename(pszFile, pszNewFile);

    if (0 != nRet)
    {
        printf("rename file failed!\n");
    }
    else
    {
        printf("################### after rename ###################\n\n");
        OutputSelfpath();
    }

    system("pause");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

GetModuleFileName:
E:\own-sources\ConsoleTest\Debug\ConsoleTest.exe

GetProcessImageFileName:
\Device\HarddiskVolume3\own-sources\ConsoleTest\Debug\ConsoleTest.exe

QueryFullProcessImageName:
E:\own-sources\ConsoleTest\Debug\ConsoleTest.exe

################### after rename ###################

GetModuleFileName:
E:\own-sources\ConsoleTest\Debug\ConsoleTest.exe

GetProcessImageFileName:
\Device\HarddiskVolume3\own-sources\ConsoleTest\Debug\ConsoleTest.exe

QueryFullProcessImageName:
E:\own-sources\ConsoleTest\Debug\ConsoleTest_bak.exe
Run Code Online (Sandbox Code Playgroud)

我已经写了一篇有关此的博客文章,请参见此处

  • 您在这里不需要 PROCESS_ALL_ACCESS 访问权限,PROCESS_QUERY_INFORMATION 或 PROCESS_QUERY_LIMITED_INFORMATION 就足够了。对于当前进程并不重要,但是如果您想获取有关其他进程的信息 - 有一些不能用 PROCESS_ALL_ACCESS 打开,但可以打开 PROCESS_QUERY_INFORMATION。 (2认同)
  • 很有用。我只是补充说,“QueryFullProcessImageName”似乎可以识别文件名修改,但不能识别文件夹名称修改。因此,如果您的重命名操作是“E:\own-sources\ConsoleTest\Debug_bak\ConsoleTest.exe”而不是“E:\own-sources\ConsoleTest\Debug\ConsoleTest_bak.exe”,那么“QueryFullProcessImageName”将无法发现它。 (2认同)