【问题标题】:How to create a new folder in %APPDATA% using C++?如何使用 C++ 在 %APPDATA% 中创建一个新文件夹?
【发布时间】:2014-07-31 23:51:40
【问题描述】:

我尝试包含 IOUtils 库并使用 CSIDL 命令,但它不起作用...

这是执行此操作的代码部分:

//------------------- Includes -----------------------
#include <fmx.h>
#include <IOUtils.hpp>
#pragma hdrstop

#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
//---------------------- end  ------------------------
//---- On Form Show (bugged event: It doesn't create the needed folder) ----

void __fastcall TfrmInicio::FormShow(TObject *Sender)
{
    if (TDirectory::Exists("CSIDL_APPDATA\\Nintersoft\\Ninterfin")) {
        if (FileExists("CSIDL_APPDATA\\Nintersoft\\Ninterfin\\Inf.nf")) {
            mmInfo->Lines->LoadFromFile("CSIDL_APPDATA\\Nintersoft\\Ninterfin\\Inf.nf");
        }
    }
    else {
            TDirectory::CreateDirectory("CSIDL_APPDATA\\Nintersoft\\Ninterfin");
    }
}

//--------------------------------- end ------------------------------------

我希望你能帮助我... 非常感谢XD

【问题讨论】:

  • 你遇到什么样的错误?
  • 它只是没有创建指定的文件夹...
  • 当然不是,因为您没有尝试要求 Windows 将 CSIDL_APPDATA 转换为真实路径。
  • 哦,我现在很困惑...我之前问过,如何在另一个主题中获取 %APPDATA% 目录,其他用户说我可以使用 CSIDL_APPDATA 或 CSIDL_LOCAL_APPDATA 作为 ROOT路径...
  • 其他用户说的是正确的,但您误读了他的答案。他没有告诉你字面上直接将"CSIDL_..." 放在你的路径字符串中。他告诉您将所需的CSIDL ID 号传递给SHGetSpecialFolderPath()。阅读我的答案,它向您展示了如何以这种方式使用CSIDL,尽管使用SHGetFolderPath() 代替(它取代了SHGetSpecialFolderPath()

标签: c++ directory firemonkey appdata c++builder-xe6


【解决方案1】:

您不应该将“CSIDL_APPDATA”本身直接硬编码到您的目录路径字符串中。 CSIDL_APPDATA 是您必须在运行时使用 Win32 API 动态解析的虚拟文件夹的 ID 号(特别是 26),例如:

void __fastcall TfrmInicio::FormShow(TObject *Sender)
{
    WCHAR szPath[MAX_PATH+1] = {0};
    if (SUCCEEDED(SHGetFolderPathW(FmxHandleToHWND(Handle), CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szPath)))
    {
        String DirPath = TPath::Combine(szPath, L"Nintersoft\\Ninterfin");
        TDirectory::CreateDirectory(DirPath);

        String FileName = TPath::Combine(DirPath, L"Inf.nf");
        if (TFile::Exists(FileName))
            mmInfo->Lines->LoadFromFile(FileName);
    }
}

或者,仅在 Vista 及更高版本上,请改用 SHGetKnownFolderPath()

void __fastcall TfrmInicio::FormShow(TObject *Sender)
{
    PWSTR pszPath;
    if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pszPath)))
    { 
        String DirPath = TPath::Combine(pszPath, L"Nintersoft\\Ninterfin");
        CoTaskMemFree(pszPath);

        TDirectory::CreateDirectory(DirPath);

        String FileName = TPath::Combine(DirPath, L"Inf.nf");
        if (TFile::Exists(FileName))
            mmInfo->Lines->LoadFromFile(FileName);
    }
}

或者,使用Sysutils::GetEnvironmentVariable() 来检索%APPDATA% 的值,而不是使用CSIDLKNOWNFOLDERID

void __fastcall TfrmInicio::FormShow(TObject *Sender)
{
    String DirPath = TPath::Combine(Sysutils::GetEnvironmentVariable(L"APPDATA"), L"Nintersoft\\Ninterfin");
    TDirectory::CreateDirectory(DirPath);

    String FileName = TPath::Combine(DirPath, L"Inf.nf");
    if (TFile::Exists(FileName))
        mmInfo->Lines->LoadFromFile(FileName);
}

【讨论】:

  • 这段代码需要一个特定的库还是只需要 winbase.h 就可以了?不好意思,我学的比较慢,我还是个C++新手
  • SHGetFolderPath()SHGetKnownFolderPath() 都在Shell32.dll 中,GetEnvironmentVariable() 在 RTL 本身中,并将 Win32 版本包装在 kernel32.dll 中。 RTL 已经为您链接到这两个库。
  • 你好,我在这里只是说我已经更改了最新的代码以在我的程序中正常工作...前两个选项我不知道为什么它不起作用C++ builer 说:未知命令,此问题发生在:SHGetKnownFolderPath; FOLDERID_RoamingAppData; CSIDL_APPDATA 和 SHGetFolderPathW。谢谢你的支持! XD
  • 您需要在代码中添加#include &lt;shlobj.h&gt; 才能使用这些功能。
  • 啊,好吧,当我问是否需要添加不同的库时,就是这样……所以,谢谢。
【解决方案2】:

我认为这应该可以帮助您 (=.

文件 NewDirectory.cpp

//includes standard libraries
#include <iostream>

//includes windows libraries
#include <windows.h>

//includes header files

int NewDirectory(){

    char *Directory = "C://Users/user/AppData/somefolder/";

    //Checks if folder of file exist
    int FilePath = PathFileExist(Directory);

    //Makes new directory
    int NewFolder = CreateDirectory(Directory, NULL);

    if(!FilePath){
        std::cout << "Error could not find folder, trying to create new Directory" << std::endl;

        NewFolder;

        if(!NewFolder){
            std::cout << "Could not make new directory closing" << std::endl;

            return 1;
        } else {
            std::cout << "New Directory" << Directory << "Created!" << std::endl;

            return 0;
        }
    } else {
        std::cout << "the Directory" << Directory << "already exist" << std::endl;

        return 0;
    }
}

【讨论】:

  • 请记住,如果目录已经存在,CreateDirectory() 将失败并出现ERROR_ALREADY_EXISTS 错误。您的示例无法处理这种情况。
  • 他特别想用%APPDATA%.的分辨率这个代码不符合。
  • 我不想告诉你这段代码确实符合要求,它会在 %appdata% 目录中创建一个文件夹,所以是的,在暗示某些事情是错误的之前,请确保你知道你在说什么。
  • 和@Remy lebeau 如果目录已经存在,我的代码会处理它,如果目录已经存在,它会输出目录已经存在。
  • @Daniel:此代码不符合用户的要求,因为您对整个路径进行了硬编码,而不是使用 %APPDATA%CSIDL_APPDATA。不同系统上的实际路径可能不同(C:\Users\&lt;user&gt;\AppData 在 Win7 之前的系统上不是默认的),这就是为什么存在%APPDATA%CSIDL_APPDATA 的原因。你知道有多少人的用户名是user
猜你喜欢
  • 2013-05-06
  • 2014-07-30
  • 1970-01-01
  • 2014-01-17
  • 2011-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-16
相关资源
最近更新 更多