Home > database >  How can I create a directory and make a file in %appdata% path of windows in C language
How can I create a directory and make a file in %appdata% path of windows in C language

Time:12-24

I successfully created a directory or folder and I also managed to create a file in that directory but how can create a directory and a file in the user's appdata local if I don't know what is their username or their user folder name? thanks!

I used codeblocks

#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void main()
{
    int check;
    char* dirname = "C:/Pyromagne";

    check = mkdir(dirname);

    FILE* fp;

    fp = fopen("C:/Pyromagne/test.pyr", "w ");
    fputs("Pyromagne\n", fp);
    fputs("qwertyuiop", fp);
    fclose(fp);

    FILE* ffpp;
    char user[25];
    char pass[25];
    char uuser[25];

    ffpp = fopen("C:/Pyromagne/test.pyr", "r");

    strcpy(uuser, fgets(user, 255, (FILE*)ffpp));
    printf("%s\n", uuser);

    strcpy(uuser, fgets(user, 255, (FILE*)ffpp));
    printf("%s\n", uuser);

    fclose(ffpp);
}

CodePudding user response:

Under MSYS2/UCRT, I recently (like yesterday...) used SHGetFolderPathA() to obtain a user's profile directory in C code.

It's worked so far in limited unit testing on a Windows Server 2016 AWS installation after being compiled with whatever GCC version comes with the latest MSYS2/UCRT installation. (The system is currently shut down and I'm on vacation so i can't check details)

This might work in your environment:

char buffer[ MAX_PATH ] = { 0 };

HRESULT result = SHGetFolderPathA( NULL, CSIDL_APPDATA, NULL, 0, buffer );
if ( result != S_OK )
{
    //handle error
}

Somewhat off-topic, I have grown to prefer MSYS2/UCRT over the alternatives.

CodePudding user response:

SHGetKnownFolderPath obtains the Unicode path to AppData, Documents, etc.

KNOWNFOLDERID for "C:\Users\MyName\AppData\Local" is FOLDERID_LocalAppData

This function needs additional libraries for CoTaskMemFree, KNOWNFOLDERID, and SHGetKnownFolderPath

gcc file.c libole32.a libuuid.a libshell32.a

Using MinGW, 64-bit, gcc version 4.8.3, I was not able to link SHGetKnownFolderPath, but you can load this function in runtime:

Example:

#define _WIN32_WINNT 0x0600
#include <stdio.h>
#include <Windows.h>
#include <shlobj.h>

HRESULT MySHGetKnownFolderPath
(const KNOWNFOLDERID* const id, DWORD flags, HANDLE token, PWSTR* str)
{
    typedef HRESULT(WINAPI* lpf)(const KNOWNFOLDERID* const, DWORD, HANDLE, PWSTR*);
    HMODULE lib = LoadLibraryW(L"shell32");
    if (!lib) return E_FAIL; 
    lpf fnc = (lpf)GetProcAddress(lib, "SHGetKnownFolderPath");
    HRESULT result = fnc ? fnc(id, flags, token, str) : E_FAIL;
    FreeLibrary(lib);
    return result;
}

int main(void)
{
    wchar_t* temp;
    if SUCCEEDED(MySHGetKnownFolderPath(&FOLDERID_LocalAppData, 0, NULL, &temp))
    {
        wchar_t path[1024];
        swprintf(path, 1024, L"%s\\_add_new_dir", temp);
        CoTaskMemFree(temp); //free this memory as soon as possible
        wprintf(L"path: %s\n", path); //CreateDirectoryW(path, NULL);
    }

    return 0;
}

Additionally, you can use getenv or _wgetenv (Unicode version)

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

int main(void)
{
    wprintf(L"%s\n", _wgetenv(L"LOCALAPPDATA"));
    wprintf(L"%s\n", _wgetenv(L"APPDATA"));
    wprintf(L"%s\n", _wgetenv(L"USERPROFILE"));

    wchar_t buf[1024];
    swprintf(buf, 1024, L"%s\\_add_new_dir", _wgetenv(L"LOCALAPPDATA"));
    wprintf(L"buf: %s\n", buf); //CreateDirectoryW(buf, NULL);
    return 0;
}
  • Related