微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++ URLDownloadToFile 到 CLR 论坛中的可执行目录

如何解决C++ URLDownloadToFile 到 CLR 论坛中的可执行目录

我想弄清楚如何解决我在 C++ 中使用 URLDownloadToFile 函数遇到的两个问题。第一个是当尝试下载有问题的文件时,在 CLR C++ 窗口关闭之前下载实际上不会出现。二是如下图所示,结果文件文件名和扩展名(在成功窗口上方)乱七八糟(虽然正常打开显示文件下载正常,但名称除外)。如果有人对我如何解决这两个问题有任何建议,我将不胜感激。

What occurs when I attempt to run this code for downloading the file in question

对于这个逻辑,我使用:

{
    char buffer[MAX_PATH];
    GetmodulefileNameA(NULL,buffer,MAX_PATH);
    std::string::size_type pos = std::string(buffer).find_last_of("\\/");

    return std::string(buffer).substr(0,pos);
}

void StartDownload()
{
    HRESULT downloadUpdate;
    LPCTSTR downloadUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png",File = "download.png";

    string currentDirectory = GetCurrentDirectory();
    LPTSTR currentDirectoryLPTSTR = new TCHAR[currentDirectory.size() + 1];

    std::string(currentDirectoryLPTSTR).append(File).c_str();

    downloadUpdate = URLDownloadToFile(0,downloadUrl,currentDirectoryLPTSTR,0);
    switch (downloadUpdate)
    {
    case S_OK:
        updateSuccess();
        break;
    case E_OUTOFMEMORY:
        updateOOMError();
        break;
    case INET_E_DOWNLOAD_FAILURE:
        updateError();
        break;
    default:
        updateErrorUnkNown();
        break;
    }
}

[STAThread]
int main() {
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Application::Run(gcnew UpdaterGUIProject::UpdaterGUI()); 

    StartDownload();

    return 0;
}

解决方法

LPTSTR currentDirectoryLPTSTR = new TCHAR[currentDirectory.size() + 1]; 分配内存,但不填充任何数据。

std::string(currentDirectoryLPTSTR) 创建一个新的 string 对象并尝试将数据从 currentDirectoryLPTSTR 复制到 string。这是未定义行为,因为 currentDirectoryLPTSTR 不是正确的以空字符结尾的字符串。此代码不会使 string 对象指向为 currentDirectoryLPTSTR 分配的内存,就像您显然认为的那样。

然后,您将 append() File 指向该 string 对象,而不是 currentDirectoryLPTSTR 的内容。

然后您丢弃刚刚创建的 string 对象,并将未填充的 currentDirectoryLPTSTR 原样传递给 URLDownloadToFile()。这就是为什么您的输出文件有一个混乱的文件名(您很幸运它甚至显示在正确的文件夹中)。

试试这个:

std::string GetCurrentDirectory()
{
    char buffer[MAX_PATH] = {};
    DWORD size = GetModuleFileNameA(NULL,buffer,MAX_PATH);
    if (size == 0 || size == MAX_PATH) return "";
    std::string fileName(buffer,size);
    std::string::size_type pos = fileName.find_last_of("\\/");
    return fileName.substr(0,pos + 1);
}

void StartDownload()
{
    HRESULT downloadUpdate;
    LPCSTR downloadUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png",File = "download.png";

    string localFile = GetCurrentDirectory() + File;

    downloadUpdate = URLDownloadToFileA(0,downloadUrl,localFile.c_str(),0);
    switch (downloadUpdate)
    {
    case S_OK:
        updateSuccess();
        break;
    case E_OUTOFMEMORY:
        updateOOMError();
        break;
    case INET_E_DOWNLOAD_FAILURE:
        updateError();
        break;
    default:
        updateErrorUnknown();
        break;
    }
}

顺便提一下,您真的不应该将文件下载到运行程序的同一文件夹中。如果您的程序安装在 C:\Program FilesC:\Program Files (x86) 之类的文件夹中,只有管理员可以写入的某个地方,那么下载可能会失败。您应该下载到用户具有写入权限的文件夹,例如您在 %APPDATA% 下创建的子文件夹,供您的程序使用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。