John Sewell
John Sewell

Reputation: 924

Save Location for Portable Executable

I want to provide my portable executable file as a single exe file.

This exe file needs some txt file to save logs. But I do not want user to delete it unintentionally.

Where is the standard way to save such kind of files by executable without requiring administrative privileges on Windows operating systems?

Portable executable also runs without requiring administrative` privileges.

Also is writing to user system by portable executable recommended? Can anti-virus software complain about that?

Upvotes: 1

Views: 1007

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31669

The executable should be installed in "C:\Program Files" or "C:\Program Files (x86)" for 32-bit programs. This installation would require admin access.

Or you can install to "c:\Users\UserName\AppData\Local" directory (or any other non-protected directory, such as "c:\My Programs"), without admin privileges, but it's unconventional.

Log files and other writable files cannot go to protected ProgramFiles directory. They should be in "c:\Users\UserName\AppData\Local".

User files must be in Documents directory.

Don't forget the program must allow the user to uninstall it. Add uninstall information to to registry key.

"c:\\Program Files\\MyCompany\\MyAppName\\app.exe"
"c:\\Users\\UserName\\AppData\\Local\\MyCompany\\MyAppName\\app.exe"

HKEY_LOCAL_MACHINE //or use HKEY_CURRENT_USER if there is no admin access
    "software\\microsoft\\windows\\currentversion\\uninstall\\My App Name"
        "UninstallString = full-path-uninstall-command"

Uninstall string is usually added to HKEY_LOCAL_MACHINE, but if the installer doesn't have admin access it can go to HKEY_CURRENT_USER

To get these folders in Vista or higher, use:

std::wstring documents, appData, programFiles;

wchar_t *ptr;
if (S_OK == SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &ptr))
{
    documents = ptr;
    CoTaskMemFree(ptr);
}

if (S_OK == SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &ptr))
{
    appData = ptr;
    CoTaskMemFree(ptr);
}

if (S_OK == SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, NULL, &ptr))
{
    programFiles = ptr;
    CoTaskMemFree(ptr);
}

Upvotes: 2

Related Questions