• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
Locked
0

Best flex directory for all users

Engaged ,
Feb 27, 2018 Feb 27, 2018

Copy link to clipboard

Copied

I'm using File.applicationStorageDirectory to store data of my app. Problem is when there are many windows users on one machine. One user has no access to others users data. I need to have common directory for all users.

In docs I see that all the OS-independent paths in Flex are based on spcific user directory. And the Application directory is read-only. So is there any directory which is common for all the users so I could store data there?

I know I could use explicit directory like:

var file:File = new File();

file.nativePath = "C:\\AIR Test";

But I need OS-independent, somewhat hidden (not in obvious place) directory.

Application

C:\Program Files\filename

Application-storage

C:\Documents and settings\userName\ApplicationData\applicationID\Local Store

Cache

C:\Documents and settings\userName\Local Settings\Temp

Desktop

C:\Documents and settings\userName\Desktop

Documents

C:\Documents and settings\userName\My Documents

Temporary

C:\Documents and settings\userName\Local Settings\Temp\randomString.tmp

User

C:\Documents and settings\userName

TOPICS
Development

Views

864

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Enthusiast , Mar 01, 2018 Mar 01, 2018

variable between % are environment variables
(same for mac but they start with $)
you can access them using the NativeProcess class

here an example

package

{

    import flash.desktop.NativeProcess;

    import flash.desktop.NativeProcessStartupInfo;

    import flash.system.Capabilities;

    import flash.events.IOErrorEvent;

    import flash.events.NativeProcessExitEvent;

    import flash.events.ProgressEvent;


    public class Test

    {

        function Test()

        {

            super();

            _setupAnd

...

Votes

Translate

Translate
Advocate ,
Feb 27, 2018 Feb 27, 2018

Copy link to clipboard

Copied

This is typically a security issue and the short answer is no you can't. Depending on admin settings in Windows or MAC users can share data or not between accounts, now that an AIR app somehow can ignore and bypass those OS security features and do whatever it wants is not likely on most system unless it was installed with admin privilege to start with.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Feb 28, 2018 Feb 28, 2018

Copy link to clipboard

Copied

"AIR app somehow can ignore and bypass those OS security features and do whatever it wants is not likely on most system unless it was installed with admin privilege to start with."

My problem started with admin who wanted to install my app for all windows users but he couldn't because I keep some important data in user specific application storage folder. So if the admin is installing the software I could bypass those security restrictions?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Feb 28, 2018 Feb 28, 2018

Copy link to clipboard

Copied

That's the idea, if a user with low privileges starts your app from his own account then likely your app won't have access to the entire system and might be blocked from using some folders. With admin privilege your app should have access to everything or at least what it needs to share across accounts.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 27, 2018 Feb 27, 2018

Copy link to clipboard

Copied

A non-os-independent solution might be:

on Mac /Users/Shared can be a place to store stuff, on Windows it's C:\Users\Public, but the actual path is different on different Windows versions (and might be different on older OSX versions as well). I suggest to do some research

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 27, 2018 Feb 27, 2018

Copy link to clipboard

Copied

You can also try C:\ProgramData which is equivalent of C:\Users\All Users, but only exists since Windows Vista.

Here's a good read about the subject: What Is the ProgramData Folder in Windows?

Also note that "C:" might be the drive letter where Windows is running from, so do a split() on File.userDirectory to make sure you're on the system drive

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Feb 28, 2018 Feb 28, 2018

Copy link to clipboard

Copied

Thanks.

I'm using windows 8 and I have C:\ProgramData and C:\Users\Public as well. So it appears I will need to detect OS version on system startup to find out which directory will keep my database. That's a problem especially that I don't know much about Mac filesystem.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Feb 28, 2018 Feb 28, 2018

Copy link to clipboard

Copied

Tracing File.userDirectory.nativePath and File.userDirectory.url on Mac shows the followings in the console:

[trace] 2/28/2018 09:28:54.094 [DEBUG] nativePath: /Users/tamas

[trace] 2/28/2018 09:28:54.096 [DEBUG] url: file:///Users/tamas

Here's the same trace on Windows

[trace] 2/28/2018 09:34:59.782 [DEBUG] native path: C:\Users\tamas

[trace] 2/28/2018 09:34:59.786 [DEBUG] url: file:///C:/Users/tamas

I think it's relatively easy to work something out from here which can work on both platforms.

Public dir on Mac is: /Users/Shared

Public dir on Windows can be: C:\Users\Public

Let me know if you need something to be tested on Mac

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Feb 28, 2018 Feb 28, 2018

Copy link to clipboard

Copied

for something that can be READ and WRITE by All users

Under Windows you want to look for %ALLUSERSPROFILE%

see CSIDL (constant special item ID list)
and KNOWNFOLDERID

let's say you want to share a file foobar.txt under the same app

you will then use %ALLUSERSPROFILE%\MyApp\foobar.txt

under Windows XP it would be

C:\Documents and Settings\All Users\MyApp\foobar.txt

under Windows 10 it would be
C:\ProgramData\MyApp\foobar.txt

for Mac OS you want to look for /Library/Application Support

eg. /Library/Application Support/MyApp/foobar.txt

but this will ask for the admin password
so as a failsafe if you can't save it there

then save it here ~/Library/Application Support/MyApp/foobar.txt

but you could also uses the following
/Library/Preferences/MyApp/

~/Library/Preferences/MyApp/

and
/Library/MyApp/

~/Library/MyApp/

see macOS Library Directory Details

Now under mac if entering the admin password is a problem
but you still need to sahre the same file/path
then use /Users/Shared/

eg. /Users/Shared/MyCompany/MyApp/foobar.txt
or even /Users/Shared/Library/Application Support/MyApp/foobar.txt

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 01, 2018 Mar 01, 2018

Copy link to clipboard

Copied

Thanks, it's really helpfull.

But I cannot find any info about how to use KNOWNFOLDERID/CSIDL in as3/flex. I've searched different combinations in google, but couldn't find anything.

This doesn't work, show an error about invalid parameter:

f = new File('%ALLUSERSPROFILE%\MyApp\foobar.txt');

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Mar 01, 2018 Mar 01, 2018

Copy link to clipboard

Copied

variable between % are environment variables
(same for mac but they start with $)
you can access them using the NativeProcess class

here an example

package

{

    import flash.desktop.NativeProcess;

    import flash.desktop.NativeProcessStartupInfo;

    import flash.system.Capabilities;

    import flash.events.IOErrorEvent;

    import flash.events.NativeProcessExitEvent;

    import flash.events.ProgressEvent;


    public class Test

    {

        function Test()

        {

            super();

            _setupAndLaunch();

        }

        private function onProcessOutput( event:ProgressEvent ):void

        {

            var data:String = _process.standardOutput.readUTFBytes( _process.standardOutput.bytesAvailable );

            trace( "stdout: " + data );

        }

        private function onProcessError( event:ProgressEvent ):void

        {

            trace("stderr: " + _process.standardError.readUTFBytes( _process.standardError.bytesAvailable ) );

        }

        private function onProcessExit( event:NativeProcessExitEvent ):void

        {

            trace( "Process exited with " + event.exitCode );

        }

       

        private function onProcessIOError( event:IOErrorEvent ):void

        {

            trace( event.toString() );

        }

        private function _getPlatform():String

        {

            var platform:String = "";

            var manufacturer:String = Capabilities.manufacturer;

           

            if( (manufacturer != "") && (manufacturer.indexOf( " " ) > -1) )

            {

                var tmp:String = manufacturer.split( " " )[1];

                platform = tmp.toLowerCase();

            }

            else

            {

                platform = manufacturer.toLowerCase();

            }

           

            return platform;

        }

        private function _setupAndLaunch():void

        {

            var filepath:String;

            var args:Vector.<String> = new Vector.<String>();

           

            switch( _getPlatform() )

            {

                case "windows":

                // very weak way to do it

                filepath = "C:\\Windows\\System32\\cmd.exe";

                args[0] = "/C";

                args[1] = "echo %USERNAME%";

                break;

               

                case "macintosh":

                case "linux":

                filepath = "/bin/sh";

                args[0] = "-c";

                args[1] = "echo $USER";

                break;

            }

           

            var file:File = new File( filepath );

           

            if( file.exists )

            {

                var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();

                    startupInfo.executable = file;

                    startupInfo.arguments = args;

   

                _process = new NativeProcess();

               

                _process.addEventListener( ProgressEvent.STANDARD_OUTPUT_DATA, onProcessOutput );

                _process.addEventListener( ProgressEvent.STANDARD_ERROR_DATA, onProcessError );

                _process.addEventListener( NativeProcessExitEvent.EXIT, onProcessExit );

                _process.addEventListener( IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onProcessIOError );

                _process.addEventListener( IOErrorEvent.STANDARD_ERROR_IO_ERROR, onProcessIOError );

               

                _process.start( startupInfo );               

            }

            else

            {

                trace( "file '" + filepath + "' does not exists" );

            }           

        }

    }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 02, 2018 Mar 02, 2018

Copy link to clipboard

Copied

LATEST

Great, thanks!

About windows comment: "very weak way to do it" you mean that windows might be installed on different drive? In that case if I want to find cmd.exe on hard drive I should do something like this:

var sFile:File = File.desktopDirectory;

var appPath:String = File.desktopDirectory.nativePath;

var driveletter:String = appPath.substr(0,3);

sFile = sFile.resolvePath(driveletter+"WINDOWS/system32");

Also instead of

args[1] = "echo %USERNAME%";

I should use

args[1] = "echo %ALLUSERSPROFILE%";

Don't know much about mac but I think I'll use your advice and put the file in /Users/Shared/

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines