plugins.txt location issues in Windows XP

Issue #13 on hold
Former user created an issue

SkyProc assumes that the plugins.txt file is located in

%APPDATA%..\Local Settings\Application Data\Skyrim\

This is wrong for two reasons:

1) Non english localizations for Windows XP use different names

and

2) %APPDATA% can be moved to a different location, outside the user profile in Windows XP, while plugins.txt is almost impossible to be moved outside the user profile for reasons that would make this report too long.

Furthermore, when SkyProc fails to find the plugins.txt file it asks the user. However, there is a bug which causes SkyProc to fail even if the correct location is pointed.

While the emphasized issue is clearly a bug, the problem with locating correct directory of plugins.txt is possibly due to Windows XP not providing a variable with its location. Of course it does exist in the registry, but I don't know if it's possible to read the Windows registry in Java without additional libraries; if it isn't you can consider the option of running a batch file to provide the correct location through:

#!

For /f "tokens=3*" %%G in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Local AppData" ^|Find "REG_"') do Call Set _localappdata=%%H

and the _localappdata variable will now contain the correct location.

Comments (25)

  1. David Tynan repo owner

    So you are reporting two bug right? 1) in windows XP SkyProc can fail to find plugins.txt, such as if it is non-english or if the user has moved %APPDATA% outside of their user folder. 2) If SkyProc fails to find plugin.txt and the user specifies it plugins.txt SkyProc still cannot locate it.

    I think I have solutions for both of these but I'm not sure how to test them as I don't have an XP system. Are you able to test?

  2. ogerboss

    The opening poster is one of my users, so I could help with the testing. Point 2) should be OS-independent and also appear on Windows 7, doesn't? Moving the plugins.txt manually should emulate this issue.

    For point 1) I could create an updated SkyProc Patcher for Requiem and upload it to my Atlassian Cloud to help with the test.

  3. Former user Account Deleted

    Yes, it seem these are 2 bugs. Sorry for posting as a single issue.

    Yes, I can help test on my XP system.

  4. Former user Account Deleted

    The new Reqtificator based on the new SkyProc library immediately found the correct plugins.txt location and worked fine.

    Even when I changed the location to a non-standard folder, I could manually point to it without problems.

    Only thing remains is to test in a non-english Windows XP locale. This will be probably done today, otherwise in the weekend.

  5. Former user Account Deleted

    According to another tester, the problem with non-localized Windows XP versions is still an issue.

    His plugins.txt folder is

    C:\Dokumente und Einstellungen\<username>\Lokale Einstellungen\Anwendungsdaten\Skyrim

    the probable cause is that SkyProc is using the %USERPROFILE% variable in order to find the correct location for local settings but then adds "\Local Settings\Application Data\Skyrim" which wont work for his non-English-localized system.

    The only way to find the correct location of the Local Application Data is to query the registry I'm afraid. That's why I provided the command above.

    Searching the net I found two interesting pieces of information:

    1) How to query Windows registry: http://www.rgagnon.com/javadetails/java-0480.html

    2) A stackoverflow.com list of answers to the problem in question: http://stackoverflow.com/questions/1198911/how-to-get-local-application-data-folder-in-java Most of them are based on the wrong assumption that Windows always uses english folder names, but user McDowell correctly states that:

    "It would be possible to spawn a process to query the key and then parse the output:

    REG QUERY "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Local AppData"

  6. David Tynan repo owner

    ogerboss did you build with the XPRegistry branch or just the main? That branch uses the registry and doesn't append "\Local Settings\Application Data\Skyrim" either. I was just waiting to merge it in once it was actually tested.

  7. ogerboss

    I just doublechecked it in SourceTree, and HEAD points to origin/XPRegistryAppData. Thus experimental patcher should be built with the correct revision.

  8. David Tynan repo owner

    Could I get a copy of the XP user's =--Debug Overview--=.txt when it fails to find his plugins.txt?

  9. Former user Account Deleted
    #!
    
    [1]                            [OPEN DEBUG FILE]  Opening Debug File
    [2]                               [Run Location]  Program running from: D:\Programme\Steam\SteamApps\common\Skyrim\Data\SkyProc Patchers\Requiem\.
    [3]                                     [Status]  Requiem for the Indifferent version: 1.8
    [4]                                     [Status]  Available Memory: 15MB
    [5]                                     [Status]  Max Memory: 247MB
    [6]                                        [SUM]  Needs update because of versioning: 0 to 1.8
    [7]                                        [SUM]  Patch needed: true
    [8]                                        [SUM]  Starting patch because user pressed patch.
    [9]                                        [SUM]  Window Closing.
    [10]                           [Needs Importing]  Needs importing because force patch was on or patch needed updating.
    [11]                                       [SUM]  Patch needed: true
    [12]                       [START IMPORT THREAD]  Starting of process thread.
    [13]                                     [ERROR]   /=== ERROR!
    [14]                                     [ERROR]  (==== File: SkyProcDebug/Get Active Mod List.txt
    [15]                                     [ERROR]   \=== Line: 2
    [16]                                     [ERROR]    \== Message: Can't locate local app data folder directly, probably running XP.
    [17]                                     [ERROR]     \========================================>
    [18]                                     [ERROR]   /=== ERROR!
    [19]                                     [ERROR]  (==== File: SkyProcDebug/Get Active Mod List.txt
    [20]                                     [ERROR]   \=== Line: 3
    [21]                                     [ERROR]    \== Message: Can't locate local app data folder.
    [22]                                     [ERROR]     \========================================>
    [23]                                 [EXCEPTION]  java.lang.NullPointerException
        at skyproc.SPGlobal.getSkyrimAppData(SPGlobal.java:342)
        at skyproc.SPGlobal.getPluginsTxt(SPGlobal.java:370)
        at skyproc.SPImporter.getActiveModList(SPImporter.java:78)
        at skyproc.SPImporter.importActiveMods(SPImporter.java:321)
        at skyproc.gui.SUMGUI$ProcessingThread.run(SUMGUI.java:925)
        at java.lang.Thread.run(Unknown Source)
    
    [24]                                       [SUM]  Closing program after UNSUCCESSFULLY running import/patch.
    
  10. Former user Account Deleted

    Shouldn't line 333 in the XPRegistryAppData branch be:

    appDataFolder = WinRegistry.readString(WinRegistry.HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", "Local AppData");
    

    instead of duplicating the WinRegistry class ?

  11. David Tynan repo owner

    Ugh. Yeah that looks right. Ogerboss can you make the change and see if that was the problem?

  12. ogerboss

    Maybe I am just too Java-ignorant, but for me it looks like WinRegistry is a package and a class inside this package at the same time. Since you have no explicit import for WinRegistry.WinRegistry you need to fully qualify it. Am I misunderstanding something here?

  13. David Tynan repo owner

    You are right ogerboss. Shows me for debugging before coffee. Anyway I pushed a new commit because winregistry was a terrible hack that couldn't read shit. I removed it and replaced it with JNA https://github.com/twall/jna#readme. You will need both JNA and JNA-Platform from that link to build it. Add them as libraries just like with Lev. With luck it will finally work.

  14. ogerboss

    That was definitely too late (1 AM in germany), but I finally got it running... Took me a few minutes to realize that NetBeans was only complaining about some internal consistency crap (your library seemed to have a different name than mine, but I could spot no difference in spelling...), while I in reality had linked all libraries properly and thus could compile the project without issues...

    @axonis1 The new patcher is uploaded, as before on the Requiem 1.8 main page.

  15. Former user Account Deleted

    Throws a "java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/WinReg" error if the Local AppData folder is not located:

    #!
    
    [1]                            [OPEN DEBUG FILE]  Opening Debug File
    [2]                               [Run Location]  Program running from: Y:\SkyProc Patchers\Requiem\.
    [3]                                     [Status]  Requiem for the Indifferent version: 1.8
    [4]                                     [Status]  Available Memory: 10MB
    [5]                                     [Status]  Max Memory: 92MB
    [6]                                        [SUM]  Needs update because of versioning: 0 to 1.8
    [7]                                        [SUM]  Patch needed: true
    [8]                                        [SUM]  Starting patch because user pressed patch.
    [9]                                        [SUM]  Window Closing.
    [10]                           [Needs Importing]  Needs importing because force patch was on or patch needed updating.
    [11]                                       [SUM]  Patch needed: true
    [12]                       [START IMPORT THREAD]  Starting of process thread.
    [13]                                     [ERROR]   /=== ERROR!
    [14]                                     [ERROR]  (==== File: SkyProcDebug/Get Active Mod List.txt
    [15]                                     [ERROR]   \=== Line: 2
    [16]                                     [ERROR]    \== Message: Can't locate local app data folder directly, probably running XP.
    [17]                                     [ERROR]     \========================================>
    [18]                                 [EXCEPTION]  java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/WinReg
        at skyproc.SPGlobal.getSkyrimAppData(SPGlobal.java:334)
        at skyproc.SPGlobal.getPluginsTxt(SPGlobal.java:368)
        at skyproc.SPImporter.getActiveModList(SPImporter.java:78)
        at skyproc.SPImporter.importActiveMods(SPImporter.java:321)
        at skyproc.gui.SUMGUI$ProcessingThread.run(SUMGUI.java:925)
        at java.lang.Thread.run(Unknown Source)
    Caused by: java.lang.ClassNotFoundException: com.sun.jna.platform.win32.WinReg
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 6 more
    
    [19]                                       [SUM]  Closing program after UNSUCCESSFULLY running import/patch.
    
  16. Former user Account Deleted

    If this is too much of a hassle, I would like to propose a different approach:

    Simply remove all registry reading (as well as all lines specific to Windows XP) and only present a warning if the LOCALAPPDATA variable is not set. It's very easy for the users to create this variable themselves, if they are presented with a few pointers, and it will work for Linux users as well without the need for WINE.

    The warning could be something like this:

    Your operating system does not provide a system variable with the location of the Local Application Data. This is required to find your plugins.txt file. You can find manually locate this file, but you can also create the LOCALAPPDATA variable manually and point it to your Local Application Data folder which contains Skyrim\plugins.txt. This location is normally at: C:\Documents and Settings\<username>\Local Settings\Application Data

    The variable, if not present, can also be safely created in a batch file:

    #!
    
    if not defined LOCALAPPDATA (
        For /f "tokens=3*" %%G in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Local AppData" ^|Find "REG_"') do Call Set LOCALAPPDATA=%%H
    )
    
  17. ogerboss

    Let's wait for some input from DienesToo, as I said I compiled this new jar-file at 1 AM, so it might very well suffer from some tiredness-induced issues on my end.

  18. David Tynan repo owner

    I'm pretty sure that exception means the libraries didn't get packed with the patcher. Did you add both jars to the patcher project as well as the skyproc project?

  19. ogerboss

    oops... I only added them to the Skyproc-project, but not to the patch project. I assumed this would suffice since the patch project has no direct dependency on it...

    I'll upload a fixed version this evening. :)

    EDIT: Do you happen to know a good tutorial about libraries and linking them in Java?

  20. ogerboss

    @axonis1 I have uploaded the new version. 4.x MB new file size vs. previously 2.5MB makes me confident that the missing stuff is now included. :D

  21. Former user Account Deleted

    Doesn't work either:

    #!
    
    [1]                            [OPEN DEBUG FILE]  Opening Debug File
    [2]                               [Run Location]  Program running from: Y:\SkyProc Patchers\Requiem\.
    [3]                                     [Status]  Requiem for the Indifferent version: 1.8
    [4]                                     [Status]  Available Memory: 10MB
    [5]                                     [Status]  Max Memory: 92MB
    [6]                                        [SUM]  Patch needed because no patch existed.
    [7]                                        [SUM]  Patch needed: true
    [8]                                        [SUM]  Starting patch because user pressed patch.
    [9]                                        [SUM]  Window Closing.
    [10]                           [Needs Importing]  Needs importing because force patch was on or patch needed updating.
    [11]                                       [SUM]  Patch needed: true
    [12]                       [START IMPORT THREAD]  Starting of process thread.
    [13]                                     [ERROR]   /=== ERROR!
    [14]                                     [ERROR]  (==== File: SkyProcDebug/Get Active Mod List.txt
    [15]                                     [ERROR]   \=== Line: 2
    [16]                                     [ERROR]    \== Message: Can't locate local app data folder directly, probably running XP.
    [17]                                     [ERROR]     \========================================>
    [18]                                  [SPGlobal]  APPDATA returned: %USERPROFILE%\Changed Local Settings Name\Changed Local AppData Name
    [19]                                  [SPGlobal]  Skyrim App data thought to be found at: %USERPROFILE%\Changed Local Settings Name\Changed Local AppData Name\Skyrim
    [20]                                  [SPGlobal]  Skyrim Plugin file location wrong. Locating manually.
    [21]                                 [EXCEPTION]  java.lang.NullPointerException
        at skyproc.SPGlobal.getPluginsTxt(SPGlobal.java:372)
        at skyproc.SPImporter.getActiveModList(SPImporter.java:78)
        at skyproc.SPImporter.importActiveMods(SPImporter.java:321)
        at skyproc.gui.SUMGUI$ProcessingThread.run(SUMGUI.java:925)
        at java.lang.Thread.run(Unknown Source)
    
    [22]                                       [SUM]  Closing program after UNSUCCESSFULLY running import/patch.
    

    The reason is that the %USERPROFILE% variable is not translated to its value.

    I think the WindowsReqistry class was a better option: not only was it smaller, but it was also based on the standard REG QUERY utility which correctly translates system variables.

  22. David Tynan repo owner

    WinRegistry was not based on REG QUERY, it was a bastard version of java preference. It also could not read the key which is why it failed in the first place. JNA is a library that bridges Java to the native windows functions and it does read the registry.

    What is the contents of your Local AppData key? Does the key contain %USERPROFILE%?

  23. Former user Account Deleted

    Yes, the Local AppData key does contains the %USERPROFILE% variable (which points to C:\Documents and Settings\<username>\ on standard systems). The contents in my test case are "%USERPROFILE%\Changed Local Settings Name\Changed Local AppData Name".

    The correct value could be taken from the following process:

    #!
    @For /f "tokens=3*" %%G in ('REG QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /v "Local AppData" ^|Find "REG_"') do @Call echo %%H
    

    (eg. in my case it returns C:\USERS\Administrator\Changed Local Settings Name\Changed Local AppData Name)

    Also, what about this simple Reg-Query-based solution ?

  24. David Tynan repo owner

    If you or ogerboss can fix it make a pull request and I'll merge it in. Baring that I'm leaving it as is and letting XP users find it themselves which works on the current main line.

  25. Log in to comment