[FR] File::setSystemAttribute()


#1

For Windows, can we get a File method to set the FILE_ATTRIBUTE_SYSTEM attribute. I need that for my installer to set a file’s attribute to RHS

Thanks,

Rail


#2

Could trigger a command line call to do the same thing if you’re not already. The issue with the hidden attribute is you might expect it to work on Mac, but hidden files on mac aren’t done with attributes they are determined based on the file name, i.e. if it starts with a ‘.’.


#3

I can simply call SetFileAttributes() which is what the File class already does for Read-Only… it’s just missing the equivalent call to set FILE_ATTRIBUTE_SYSTEM in the class. Yes, this is a Windows only flag… but if you check out the File class you can see they don’t implement setFileExecutableInternal() on Windows so they can use the same style for setSystemAttribute().

Cheers,

Rail


#4

I guess I want something like:

bool setFileAttributes (const File& path, const DWORD dwAttributes)
{
    if (! path.exists())
        return false;

    std::string fullPath = path.getFullPathName().toStdString();

    const DWORD oldAtts = GetFileAttributes ((LPCTSTR) fullPath.c_str());

    if (oldAtts == INVALID_FILE_ATTRIBUTES)
        return false;

    const DWORD newAtts = dwAttributes ? (oldAtts |  dwAttributes) : (oldAtts & ~dwAttributes);

    return newAtts == oldAtts || SetFileAttributes ((LPCTSTR) fullPath.c_str(), newAtts) != FALSE;
}

Rail


#5

OK, I’ve tidied this up internally - try juce::WindowsFileHelpers::changeAtts()

And be careful if you write things like (LPCTSTR) fullPath.c_str() because a TSTR could be wide or not depending on your build, so you could be reinterpreting an 8-bit string as a wide one. That’s why I used toWideCharPointer() in the code that you modified for this.


#6

@jules Just looking at your commit, GetFileAttributes isn’t guaranteed noexcept - wouldn’t that risk breaking the promise that getAtts is noexcept and have other pitfalls?


#7

GetFileAttributes is a C function, so can’t throw exceptions (?)


#8

Thanks Jules. Noted on the toWideCharPointer().

I am having trouble using juce::WindowsFileHelpers::changeAtts() due to the namespace not being found… I’m wondering if I need to include something… I’ll dig into this later today when I get a mo’ - it has to be a scope issue.

Thanks,

Rail


#9

I didn’t make it public, but you can sneakily link into internal functions like that by declaring them yourself, .e.g.

namespace juce
{
    namespace WindowsFileHelpers
    {
        bool changeAtts (const String& etc...
    }
}