获取.exe目录中列出的所有文件,不知道位置

Get all files listed inside .exe directory not knowing location

本文关键字:文件 位置 不知道 exe 获取      更新时间:2023-10-16

我想我的问题是-我如何获得exe位置的目录作为LPCWSTR,以便我可以将其输入到我的代码

#include <iostream>
#include <Windows.h>
int main(int argc, char **argv)
{
WIN32_FIND_DATA a;
HANDLE swap = FindFirstFile(/*(LPCWSTR)__exe_directory__*/,&a);
if (swap!=INVALID_HANDLE_VALUE)
{
    do
    {
        char *sptn = new char [lstrlen(a.cFileName)+1];
        for (int c=0;c<lstrlen(a.cFileName);c++)
        {
            sptn[c]=char(a.cFileName[c]);
        }
        sptn[lstrlen(a.cFileName)]='';
        std::cout<<sptn<<std::endl;
    }
    while (FindNextFile(swap,&a));
}
else std::cout<<"undetected filen";
FindClose(swap);
system("pause");
}

并且它将返回目录中列出的文件而不会出错。我知道我的代码已经在给定的目录下工作了,我已经测试过了。

关键是使用 GetModuleFileName() (传递nullptr作为模块句柄,以引用当前进程EXE),然后调用 PathRemoveFileSpec() (或PathCchRemoveFileSpec(),如果你不关心Windows 8之前的Windows版本)从路径中剥离文件规范。

要使用PathRemoveFileSpec(),必须链接到Shlwapi。如MSDN文档中所述。

查看以下可编译代码示例:

#include <iostream>     // For console output
#include <exception>    // For std::exception
#include <stdexcept>    // For std::runtime_error
#include <string>       // For std::wstring
#include <Windows.h>    // For Win32 SDK
#include <Shlwapi.h>    // For PathRemoveFileSpec()
#pragma comment(lib, "Shlwapi.lib")
// Represents an error in a call to a Win32 API.
class win32_error : public std::runtime_error 
{
public:
    win32_error(const char * msg, DWORD error) 
        : std::runtime_error(msg)
        , _error(error)
    { }
    DWORD error() const 
    {
        return _error;
    }
private:
    DWORD _error;
};
// Returns the path without the filename for current process EXE.
std::wstring GetPathOfExe() 
{
    // Get filename with full path for current process EXE
    wchar_t filename[MAX_PATH];
    DWORD result = ::GetModuleFileName(
        nullptr,    // retrieve path of current process .EXE
        filename,
        _countof(filename)
    );
    if (result == 0) 
    {
        // Error
        const DWORD error = ::GetLastError();
        throw win32_error("Error in getting module filename.", 
                          error);
    }
    // Remove the file spec from the full path
    ::PathRemoveFileSpec(filename);
    return filename;
}
int main() 
{
    try 
    {
        std::wcout << "Path for current EXE:n"
                   << GetPathOfExe() 
                   << std::endl;
    } 
    catch (const win32_error & e) 
    {
        std::cerr << "n*** ERROR: " << e.what()
                  << " (error code: " << e.error() << ")" 
                  << std::endl;
    } 
    catch (const std::exception& e) 
    {
        std::cerr << "n*** ERROR: " << e.what() << std::endl;
    }
}
在控制台:

C:TempCppTests>cl /EHsc /W4 /nologo /DUNICODE /D_UNICODE get_exe_path.cpp
get_exe_path.cpp
C:TempCppTests>get_exe_path.exe
Path for current EXE:
C:TempCppTests

p
在您的代码中,您似乎指的是FindFirtFile()的Unicode版本(即FindFirstFileW(),因为在评论中您期望LPCWSTR,即const wchar_t*),但随后在以下代码中您使用ANSI/MBCS字符串(即char*)。

我建议你在现代Windows c++代码中始终使用Unicode UTF-16 wchar_t*字符串:它更适合国际化,现代Win32 api只提供Unicode版本。

还请注意,由于您正在使用c++,因此最好使用一个健壮的方便的字符串类(例如,Microsoft Visual c++中Unicode UTF-16字符串的std::wstring),而不是类似C的原始字符指针。在API接口使用原始指针(因为Win32 API有一个C接口),然后安全地转换为std::wstring

使用GetModuleFileName函数,在UNICODE构建中,以宽字符串形式获取可执行的完整文件名。

然后,搜索最后一个''字符并将其替换为0。

#include <Windows.h>
#include <stdio.h>
int main( void ) {
    wchar_t szExeFullPath[ MAX_PATH ];
    if ( GetModuleFileName( NULL, szExeFullPath, _countof( szExeFullPath ) ) ) {
        wchar_t * pszLastAntiSlash = wcsrchr( szExeFullPath, L'' );
        if ( pszLastAntiSlash ) {
            *pszLastAntiSlash = 0;
            wprintf( L"Exe full path is %sn", szExeFullPath );
        }
    }
    return 0;
}