- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does anyone have a nice way to get the path the user's "My Documents" directory from Intel Fortran?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
More information: My application includes an installer project in Visual Studio 2010. Basically, I want to have the installer create a directory to put examples and scratch files in that the application will use. In the application, when the user wants to open a file, this is the directory I want to be the default that they are taken to. I can make the installer install the files using the "User's Personal Data" item in the file system tree. However, I can't seem to figure out how to get the application to know where this is located. I can get the location of the user's home directory with the "USERPROFILE" environment variable, but there doesn't seem to be an environment variable for the user's documents folder. I'd like a nice way to do this that works on Windows 7 and beyond (XP is a plus, but not required), that doesn't require me hard-coding what the directory is called (which may vary from system to system).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
See the SHGetFolderPath API and its friends, and query the path location for CSIDL_PERSONAL.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For a full list of CSIDL values useable by SHGetFolderPath see
http://msdn.microsoft.com/en-gb/library/windows/desktop/bb762494%28v=vs.85%29.aspx
There you can see that CSIDL_MYDOCUMENTS is the same as CSIDL_PERSONAL
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
All of these CSIDL values are available through the XSystemPath function in the Xeffort library, if you want to avoid working with the API directly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks all! My solution is below. It seems to work (note that it requires linking with shell32.lib). Not sure if there is a better way to deal with the C string?
program test use iso_c_binding use kernel32 use ifwinty implicit none integer :: i integer(handle) :: hresult character(len=1),dimension(256) :: tmpstr character(len=:),allocatable :: MyDocumentsDir integer(HANDLE),parameter :: CSIDL_PERSONAL = 5 !from Shlobj.h interface function SHGetFolderPathA(hwndOwner,nFolder,hToken,dwFlags,pszPath) !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'SHGetFolderPathA' :: SHGetFolderPathA import implicit none integer(HANDLE) :: SHGetFolderPathA integer(HANDLE),value :: hwndOwner integer(c_int),value :: nFolder integer(HANDLE),value :: hToken integer(DWORD),value :: dwFlags character(kind=C_CHAR) :: pszPath(*) end function SHGetFolderPathA end interface hresult = SHGetFolderPathA( hwndOwner= NULL, & nFolder = CSIDL_PERSONAL,& hToken = NULL,& dwFlags = 0,& pszPath = tmpstr) write(*,*) 'hresult=',hresult if (hresult==0) then !convert array to character string: MyDocumentsDir = '' do i=1,size(tmpstr) if (tmpstr(i)/=C_NULL_CHAR) then MyDocumentsDir = MyDocumentsDir//tmpstr(i) else exit end if end do write(*,*) 'MyDocumentsDir: '//MyDocumentsDir else write(*,*) 'Error' end if end program test
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Given that it is the ANSI version you have interfaced to why not make the interface more Fortran friendly by having
character
(len=*
) :: pszPath
And then you can get
MyDocumentsDir direct from the call without the string array copy? If you wanted the position of the first C_NULL_CHAR you could use INDEX. Also add !DEC$OBJCOMMENT LIB:"SHELL32.LIB" perhaps.
@Intel is there any plans to add any new APIs to the IFWIN interfaces? There are many missing ones. I note the shell32 interfaces have not been added since 2000. It is after all Visual Fortran for WINDOWS!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
app4619, yes, we do plan to add APIs. It's a time-consuming process, though. I'll take a look at shell32.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@Jacob
You might note that SHGetFolderPath is supperceded SHGetKnownFolderPath which had more options. Also:
You have the function return value as type handle, HRESULT would be better with ifwinty type LONG (4 bytes) your code should fail on x64 as it will be 8 bytes.
I also note the use of VALUE attribute. This is default for stdcall except for arrays and type character in my understanding.
@steve thanks. Some updates would be appreciated. I know it is time consuming, it consumes some of my time!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the suggestions! I did look at SHGetKnownFolderPath, but wasn't sure about the Fortran bindings for the REFKNOWNFOLDERID argument. I might revisit it later.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, WinINet.lib would also be a good one to have.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page