system directories on Windows builds

I published an iOS / Android game a couple years back, and now I’m looking to make a windows version. I was able to get things running pretty quickly - even my custom level stuff, which reads & writes local files.

However, on Windows I would like to control WHERE those custom writes occur - no procedurally-named directories. I want to specify a “my levels” folder inside the app folder.

The online documentation for system.pathForFile doesn’t seem to cover windows cases very well. Anyone with experience able to help me out here?

It is very unlikely that Windows will let your app write to the ‘app folder’ (by which I assume you mean the home of the executable).  

You may consider writing to the user’s document folder though.

As far as discovering that directory, you’ll need to make some os.* calls and dig through system variables to piece together the location of the user’s documents folder and/or the desktop.

I’m still working on this for myself, but here is one snippet of code from my own WIP solution.

local desktopPath = os.getenv("appdata") local appDataStart = string.find( desktopPath, "AppData" ) if( appDataStart ) then desktopPath = string.sub( desktopPath, 1, appDataStart-1 ) desktopPath = desktopPath .. "Desktop\\" end

The above code works out the ‘desktop’ path for the current users.  You can elaborate from here.

-Ed

Hmmm… this implies to me that I could pass in any path via string. When I do os.getenv the string I’m returned is:

C:\Users\myusername\AppData\Roaming

Looks great! So I try sticking that into my path variable via:

local path = system.pathForFile("TestFile.txt", "C:\Users\myusername\AppData\Roaming")

But that returns nil - it doesn’t like that as a path. Which doesn’t make any sense to me…

I feel like I’m missing something important here about how lua reads & interprets string paths.

You don’t need to use ‘system.pathForFile()’.  The code I gave you already gives you the absolute path to the folder.  

“C:\Users_<user name goes here>_\AppData\Roaming” is a complete path already (minus the user name part).

‘system.pathForFile()’ is a helper function to determine the absolute  path of a folder based on a specified context.  It isn’t used to modify a path which is already complete/absolute.

Oh, and yes.  You can use any valid path for reading and writing files, as long as the OS, malware checkers, virus checkers, etc. let you.

We document where Corona’s sandboxed directories are located for a Win32 built app here…

   https://docs.coronalabs.com/daily/guide/distribution/win32Build/index.html#building-running

For your quick reference, the DocumentsDirectory, TemporaryDirectory, and CachesDirectory are located under the system’s hidden “Users\<LoginName>\AppData*” directory.  The subdirectories it goes under depends on the “Company Name” and “Application Name” that you’ve entered for your app in the build dialog.  Note that this correctly follows Microsoft’s convention for storing app data that you normally would not reveal to end-users.

Now, you do have the ability to use the LFS (Lua File System) library and Lua’s file APIs to access files/directories outside of Corona’s sandboxed directories.  ***BUT*** most of Corona’s APIs such as display.* and system.* do not support accessing files outside of its sandbox.  This restriction is designed for compatibility/portability with mobile platforms such as Android and iOS.  But, you can use the non-Corona APIs such as LFS and file.* like I mentioned above without this restriction.

It is very unlikely that Windows will let your app write to the ‘app folder’ (by which I assume you mean the home of the executable).  

You may consider writing to the user’s document folder though.

As far as discovering that directory, you’ll need to make some os.* calls and dig through system variables to piece together the location of the user’s documents folder and/or the desktop.

I’m still working on this for myself, but here is one snippet of code from my own WIP solution.

local desktopPath = os.getenv("appdata") local appDataStart = string.find( desktopPath, "AppData" ) if( appDataStart ) then desktopPath = string.sub( desktopPath, 1, appDataStart-1 ) desktopPath = desktopPath .. "Desktop\\" end

The above code works out the ‘desktop’ path for the current users.  You can elaborate from here.

-Ed

Hmmm… this implies to me that I could pass in any path via string. When I do os.getenv the string I’m returned is:

C:\Users\myusername\AppData\Roaming

Looks great! So I try sticking that into my path variable via:

local path = system.pathForFile("TestFile.txt", "C:\Users\myusername\AppData\Roaming")

But that returns nil - it doesn’t like that as a path. Which doesn’t make any sense to me…

I feel like I’m missing something important here about how lua reads & interprets string paths.

You don’t need to use ‘system.pathForFile()’.  The code I gave you already gives you the absolute path to the folder.  

“C:\Users_<user name goes here>_\AppData\Roaming” is a complete path already (minus the user name part).

‘system.pathForFile()’ is a helper function to determine the absolute  path of a folder based on a specified context.  It isn’t used to modify a path which is already complete/absolute.

Oh, and yes.  You can use any valid path for reading and writing files, as long as the OS, malware checkers, virus checkers, etc. let you.

We document where Corona’s sandboxed directories are located for a Win32 built app here…

   https://docs.coronalabs.com/daily/guide/distribution/win32Build/index.html#building-running

For your quick reference, the DocumentsDirectory, TemporaryDirectory, and CachesDirectory are located under the system’s hidden “Users\<LoginName>\AppData*” directory.  The subdirectories it goes under depends on the “Company Name” and “Application Name” that you’ve entered for your app in the build dialog.  Note that this correctly follows Microsoft’s convention for storing app data that you normally would not reveal to end-users.

Now, you do have the ability to use the LFS (Lua File System) library and Lua’s file APIs to access files/directories outside of Corona’s sandboxed directories.  ***BUT*** most of Corona’s APIs such as display.* and system.* do not support accessing files outside of its sandbox.  This restriction is designed for compatibility/portability with mobile platforms such as Android and iOS.  But, you can use the non-Corona APIs such as LFS and file.* like I mentioned above without this restriction.