zoukankan      html  css  js  c++  java
  • Windows获取进程完整路径

    #include <stdio.h>
    #include <locale.h>
    #include <windows.h>
    #include <tlhelp32.h>
    #include <tchar.h>
    #include <Psapi.h>
    #pragma comment (lib,"Psapi.lib")
    
    
    BOOL DosPathToNtPath(LPTSTR pszDosPath, LPTSTR pszNtPath)
    {
        TCHAR            szDriveStr[500];
        TCHAR            szDrive[3];
        TCHAR            szDevName[100];
        INT                iDevName;
        INT                i;
    
        //检查参数
        if (!pszDosPath || !pszNtPath)
            return FALSE;
    
        //获取本地磁盘所有盘符,以'\0'分隔,所以下面+4
        if (GetLogicalDriveStrings(sizeof(szDriveStr), szDriveStr))
        {
            for (i = 0; szDriveStr[i]; i += 4)
            {
                if (!lstrcmpi(&(szDriveStr[i]), _T("A:\\")) || !lstrcmpi(&(szDriveStr[i]), _T("B:\\")))
                    continue;    //从C盘开始
    
                //盘符
                szDrive[0] = szDriveStr[i];
                szDrive[1] = szDriveStr[i + 1];
                szDrive[2] = '\0';
                if (!QueryDosDevice(szDrive, szDevName, 100))//查询 Dos 设备名(盘符由NT查询DOS)
                    return FALSE;
    
                iDevName = lstrlen(szDevName);
                if (_tcsnicmp(pszDosPath, szDevName, iDevName) == 0)//是否为此盘
                {
                    lstrcpy(pszNtPath, szDrive);//复制驱动器
                    lstrcat(pszNtPath, pszDosPath + iDevName);//复制路径
    
                    return TRUE;
                }
            }
        }
    
        lstrcpy(pszNtPath, pszDosPath);
    
        return FALSE;
    }
    //获取进程完整路径
    BOOL GetProcessFullPath(DWORD dwPID)
    {
        TCHAR        szImagePath[MAX_PATH];
        TCHAR        pszFullPath[MAX_PATH];
        HANDLE        hProcess;
        if (!pszFullPath)
            return FALSE;
    
        pszFullPath[0] = '\0';
    
        hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPID);    //由线程ID获得线程信息
        if (!hProcess)
            return FALSE;
    
        if (!GetProcessImageFileName(hProcess, szImagePath, MAX_PATH))    //得到线程完整DOS路径
        {
            CloseHandle(hProcess);
            return FALSE;
        }
        if (!DosPathToNtPath(szImagePath, pszFullPath))    //DOS路径转NT路径
        {
            CloseHandle(hProcess);
            return FALSE;
        }
    
    
    
        CloseHandle(hProcess);
    
        _tprintf(_T("%5d  %s \r\n"), dwPID, pszFullPath);
        return TRUE;
    }
    int main(int argc, char* argv[])
    {
        setlocale(LC_ALL, "chs");    //不设置解析中文字符时可能会出问题
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);    //得到系统所有线程快照
        if (INVALID_HANDLE_VALUE == hSnapshot)
        {
            return NULL;
        }
        PROCESSENTRY32 pe = { 0 };
        pe.dwSize = sizeof(PROCESSENTRY32);
    
        BOOL fOk;
        for (fOk = Process32First(hSnapshot, &pe); fOk; fOk = Process32Next(hSnapshot, &pe))    //遍历
        {
            GetProcessFullPath(pe.th32ProcessID);
        }
        return 0;
    }

    为什么要使用setlocal呢(非本例)

    在 VC2005 中 std::fstream 的打开文件的函数实现里,传入的 char const* 文件名作为多字节首先被mbstowcs 转换成宽字节后,再转发给 Unicode 版本的 API 进行实际的打开文件操作

    _MRTIMP2_NCEEPURE FILE *__CLRCALL_PURE_OR_CDECL _Fiopen(const char *filename, ios_base::openmode mode, int prot) 
    { // open wide-named file with byte name wchar_twc_name[FILENAME_MAX];   if (mbstowcs_s(NULL, wc_name, FILENAME_MAX, filename,FILENAME_MAX - 1) != 0)
        return (0); 
    return _Fiopen(wc_name, mode, prot); 
    }

    问题的关键在于,对于 mbstowcs 函数来说,它需要知道多字节的编码类型才能正确的将其转换成宽字节的 unicode,很可惜这个编码类型并没有体现在函数的参数列表里,而是隐含依赖全局的 locale 。更加不幸的是,全局 locale 默认没有使用系统当前语言,而是设置为没什么用处的 "C" locale 。于是 GBK 编码的文件名在 "C" locale 下转换错误

    在本机上vs2017运行本例时出现了无法打印中文字符串的现象

  • 相关阅读:
    一個SQL排序的問題[轉]
    行數據轉換成列數據
    asp页面转化成htm静态页面
    DataGrid 中間隔色的實現
    asp.net里导出excel表方法汇总[轉]
    C#中计算两个时间的差
    asp.net面试的题目
    页面间传输中文的乱码解决方法
    NickLee 多層菜單
    Add an onclick event in the DataGrid for any Column
  • 原文地址:https://www.cnblogs.com/chenxingyang/p/9780341.html
Copyright © 2011-2022 走看看