Skip to content

Commit 44ab414

Browse files
committed
attempt alternate settings path on windows, use simpler getter for documents, and more informative appdata error messages (#3838)
1 parent 962ef24 commit 44ab414

2 files changed

Lines changed: 50 additions & 38 deletions

File tree

app/src/processing/app/Base.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,20 +1726,20 @@ static public File getSettingsFolder() {
17261726

17271727
try {
17281728
settingsFolder = Platform.getSettingsFolder();
1729+
1730+
// create the folder if it doesn't exist already
1731+
if (!settingsFolder.exists()) {
1732+
if (!settingsFolder.mkdirs()) {
1733+
Messages.showError("Settings issues",
1734+
"Processing cannot run because it could not\n" +
1735+
"create a folder to store your settings.\n" +
1736+
settingsFolder.getAbsolutePath(), null);
1737+
}
1738+
}
17291739
} catch (Exception e) {
17301740
Messages.showError("Problem getting the settings folder",
17311741
"Error getting the Processing the settings folder.", e);
17321742
}
1733-
1734-
// create the folder if it doesn't exist already
1735-
if (!settingsFolder.exists()) {
1736-
if (!settingsFolder.mkdirs()) {
1737-
Messages.showError("Settings issues",
1738-
"Processing cannot run because it could not\n" +
1739-
"create a folder to store your settings.\n" +
1740-
settingsFolder.getAbsolutePath(), null);
1741-
}
1742-
}
17431743
return settingsFolder;
17441744
}
17451745

app/src/processing/app/platform/WindowsPlatform.java

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,14 @@
2828

2929
import com.sun.jna.Library;
3030
import com.sun.jna.Native;
31-
import com.sun.jna.platform.win32.Kernel32Util;
32-
import com.sun.jna.platform.win32.Shell32;
3331
import com.sun.jna.platform.win32.Shell32Util;
3432
import com.sun.jna.platform.win32.ShlObj;
35-
import com.sun.jna.platform.win32.WinDef;
36-
import com.sun.jna.platform.win32.WinError;
37-
import com.sun.jna.platform.win32.WinNT.HRESULT;
3833

3934
import processing.app.Base;
4035
import processing.app.Messages;
4136
import processing.app.Preferences;
42-
import processing.app.platform.DefaultPlatform;
4337
import processing.app.platform.WindowsRegistry.REGISTRY_ROOT_KEY;
38+
4439
import processing.core.PApplet;
4540

4641

@@ -260,11 +255,29 @@ protected void checkPath() {
260255

261256
// looking for Documents and Settings/blah/Application Data/Processing
262257
public File getSettingsFolder() throws Exception {
263-
String appData = getAppDataPath();
264-
if (appData != null) {
265-
return new File(appData, APP_NAME);
258+
String appDataRoaming = getAppDataPath();
259+
if (appDataRoaming != null) {
260+
File settingsFolder = new File(appDataRoaming, APP_NAME);
261+
if (settingsFolder.exists() || settingsFolder.mkdirs()) {
262+
return settingsFolder;
263+
}
264+
}
265+
266+
String appDataLocal = getLocalAppDataPath();
267+
if (appDataLocal != null) {
268+
File settingsFolder = new File(appDataLocal, APP_NAME);
269+
if (settingsFolder.exists() || settingsFolder.mkdirs()) {
270+
return settingsFolder;
271+
}
272+
}
273+
274+
if (appDataRoaming == null && appDataLocal == null) {
275+
throw new IOException("Could not get the AppData folder");
266276
}
267-
throw new IOException("Could not get the Application Data folder");
277+
278+
// https://github.com/processing/processing/issues/3838
279+
throw new IOException("Please fix permissions for either " +
280+
appDataRoaming + " or " + appDataLocal);
268281
}
269282

270283

@@ -279,31 +292,21 @@ public File getSettingsFolder() throws Exception {
279292
280293
http://blogs.msdn.com/b/patricka/archive/2010/03/18/where-should-i-store-my-data-and-configuration-files-if-i-target-multiple-os-versions.aspx
281294
*/
295+
296+
297+
/** Get the Users\name\AppData\Roaming path to write settings files. */
282298
static private String getAppDataPath() throws Exception {
283299
return Shell32Util.getSpecialFolderPath(ShlObj.CSIDL_APPDATA, true);
300+
}
284301

285-
/*
286-
// this will be contain the path if SHGetFolderPath is successful
287-
char[] pszPath = new char[WinDef.MAX_PATH];
288-
HRESULT hResult =
289-
Shell32.INSTANCE.SHGetFolderPath(null, ShlObj.CSIDL_APPDATA,
290-
null, ShlObj.SHGFP_TYPE_CURRENT,
291-
pszPath);
292-
293-
if (!hResult.equals(WinError.S_OK)) {
294-
//System.err.println(Kernel32Util.formatMessageFromHR(hResult));
295-
//throw new Exception("Problem city, population: your computer.");
296-
throw new Exception(Kernel32Util.formatMessageFromHR(hResult));
297-
}
298302

299-
String appDataPath = new String(pszPath);
300-
int len = appDataPath.indexOf("\0");
301-
return appDataPath.substring(0, len);
302-
*/
303+
/** Get the Users\name\AppData\Local path as a settings fallback. */
304+
static private String getLocalAppDataPath() throws Exception {
305+
return Shell32Util.getSpecialFolderPath(ShlObj.CSIDL_LOCAL_APPDATA, true);
303306
}
304307

305308

306-
// looking for Documents and Settings/blah/My Documents/Processing
309+
/** Get the Documents and Settings\name\My Documents\Processing folder. */
307310
public File getDefaultSketchbookFolder() throws Exception {
308311
String documentsPath = getDocumentsPath();
309312
if (documentsPath != null) {
@@ -313,6 +316,12 @@ public File getDefaultSketchbookFolder() throws Exception {
313316
}
314317

315318

319+
static private String getDocumentsPath() throws Exception {
320+
return Shell32Util.getSpecialFolderPath(ShlObj.CSIDL_MYDOCUMENTS, true);
321+
}
322+
323+
324+
/*
316325
static private String getDocumentsPath() throws Exception {
317326
// heh, this is a little too cheeky
318327
//new JFileChooser().getFileSystemView().getDefaultDirectory().toString();
@@ -351,6 +360,7 @@ static private String getDocumentsPath() throws Exception {
351360
int len = personalPath.indexOf("\0");
352361
return personalPath.substring(0, len);
353362
}
363+
*/
354364

355365

356366
// @Override
@@ -503,6 +513,8 @@ public void openFolder(File file) throws Exception {
503513
static WinLibC clib;
504514

505515

516+
// moved to a getter so that we could handle errors in a single location
517+
// and at a time when it was useful/possible (rather than a static block)
506518
static WinLibC getLibC() {
507519
if (clib == null) {
508520
try {

0 commit comments

Comments
 (0)