The developers investigated this matter and provided the explanation for it below. We hope that you find this information useful and would welcome any comments you have on it.
When the APL+Win ActiveX Server component is instantiated behind a Windows service, it is important to understand the user profile which is loaded by that Windows service. A Windows service runs in the security context of a specified user account. The user name and password are used by the CreateService function at the time the service is installed on the server hardware. The user name and password associated with a Windows service can be modified using the ChangeServiceConfig function. The QueryServiceConfig function may be used to obtain the user name, but not the password associated with a service.
When the Windows service starts the Microsoft Service Control Manager (SCM) uses the credentials of the user account associated with the service, however the SCM loads the user profile associated with the SCM and not the user profile associated with the user account under which the service runs.
This behavior is by Microsoft design and is not a function of APL+Win or APLNext Application Web Services. Go to
http://msdn.microsoft.com/en-gb/library/windows/desktop/ms686005(v=vs.85).aspx for more information.
This means that an application, such as the APL+Win Server ActiveX component, running under a Windows service will have access to the SCM user profile using the associated Win32 API methods. In this scenario APL+Win use of the Win32 API to obtain user profile information, e.g. from Windows environment variables, may yield unexpected results.
For example ⎕wcall 'ExpandEnvironmentStrings' ‘%appdata%’ (512⍴⎕tcnul) 512 may not return the expected application data folder path specific to the service user’s credential, e.g. ‘myusername.mydomain’. That Win32 API method will return the application data folder path for the SCM user profile, e.g. “c:\windows\system32\config\systemprofile\AppData\Roaming” and not “C:\Users\ myusername\Roaming”.
There is an alternate method, the Windows Registry, for obtaining the “%appdata%” folder path for the profile associated with the user account under which the Windows service is running from on the target server. The following illustrates how to obtain this folder path from the Windows Registry:
- Code: Select all
The line below replaces your line in the APL function Show that retrieves the AppData folder path:
z←z,⎕tcnl,'<p><b>AppData (Registry): </b><br>', Profile 'AppData'
where Profile (code shown below), in the line above, is a new APL function.
∇ res←Profile data;∆key
[1]
[2] ⍝ Sources:
[3] ⍝ http://www.lubby.org/result.jsf?DB=lkb_windows_english&ID=154
[4] ⍝ http://superuser.com/questions/681588/environment-variable-for-hkey-users-software
[5] ⍝
[6] ⍝ Makes use of the APL2000 Registry ActiveX control
[7] ⍝
[8] ⍝ Copyright 2015 APLNow LLC. -- John Walker
[9]
[10] ⎕wself←'∆reg' ⎕wi 'Create' 'apl2000.regkey'
[11]
[12] :if (⍴SID) > 12
[13] ∆key←'HKU\',SID,'\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
[14] :else
[15] ⍝ Support logon as "Local System Account"
[16] ∆key←'HKU\',SID,'\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'
[17] :end
[18] ⎕wi 'xKeyName' ∆key
[19] res←⎕wi 'GetValue' data
∇
Profile then calls another function SID (code shown below) that retrieves the sid (security identifier) for the user that is logged on.
∇ res←SID;name
[1] ⍝ Copyright 2015 APLNow LLC. -- John Walker
[2]
[3] ⎕nuntie ⎕nnums
[4] 3 ⎕cmd 'whoami /user > who2.txt'
[5] 'who2.txt' ⎕ntie ¯1
[6] name←(⎕nread ¯1,82,(⎕nsize ¯1),0)~⎕tcnl,⎕tclf
[7] res←⌽(¯1+((⌽name)='\')⍳1)↑(⌽name)
[8] res←(¯1+(res ⎕ss 'S-1')⍳1)↓res
∇
The functions, Profile and SID, are included in the workspace in the attachment.