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;
}