Microsoft KB Archive/210860: Difference between revisions
m (Text replacement - ">" to ">") |
m (Text replacement - "&" to "&") |
||
Line 127: | Line 127: | ||
' ----Begin Get 32 Bit Registry Entry Value Declarations---- | ' ----Begin Get 32 Bit Registry Entry Value Declarations---- | ||
Const HKEY_CURRENT_USER = & | Const HKEY_CURRENT_USER = &H80000001 | ||
Const ERROR_SUCCESS = 0& | Const ERROR_SUCCESS = 0& | ||
Const REG_DWORD = 4 | Const REG_DWORD = 4 | ||
Const REG_BINARY = 3 | Const REG_BINARY = 3 | ||
Line 144: | Line 144: | ||
Const ERROR_INVALID_PARAMETERS = 87 | Const ERROR_INVALID_PARAMETERS = 87 | ||
Const ERROR_NO_MORE_ITEMS = 259 | Const ERROR_NO_MORE_ITEMS = 259 | ||
Const KEY_ALL_ACCESS = & | Const KEY_ALL_ACCESS = &H3F | ||
Const REG_OPTION_NON_VOLATILE = 0 | Const REG_OPTION_NON_VOLATILE = 0 | ||
Line 206: | Line 206: | ||
' Determine the size and type of data to be read. | ' Determine the size and type of data to be read. | ||
lrc = RegQueryValueExNULL(lhKey, szValueName, 0& | lrc = RegQueryValueExNULL(lhKey, szValueName, 0&, lType, 0&, cch) | ||
If lrc <> ERROR_NONE Then Error 5 | If lrc <> ERROR_NONE Then Error 5 | ||
Select Case lType | Select Case lType | ||
Line 212: | Line 212: | ||
Case REG_SZ: | Case REG_SZ: | ||
sValue = String(cch, 0) | sValue = String(cch, 0) | ||
lrc = RegQueryValueExString(lhKey, szValueName, 0& | lrc = RegQueryValueExString(lhKey, szValueName, 0&, lType, _ | ||
sValue, cch) | sValue, cch) | ||
If lrc = ERROR_NONE Then | If lrc = ERROR_NONE Then | ||
Line 221: | Line 221: | ||
Case REG_EXPAND_SZ: | Case REG_EXPAND_SZ: | ||
sValue = String(cch, 0) | sValue = String(cch, 0) | ||
lrc = RegQueryValueExString(lhKey, szValueName, 0& | lrc = RegQueryValueExString(lhKey, szValueName, 0&, lType, _ | ||
sValue, cch) | sValue, cch) | ||
If lrc = ERROR_NONE Then | If lrc = ERROR_NONE Then | ||
Line 229: | Line 229: | ||
End If | End If | ||
Case REG_DWORD: | Case REG_DWORD: | ||
lrc = RegQueryValueExLong(lhKey, szValueName, 0& | lrc = RegQueryValueExLong(lhKey, szValueName, 0&, lType, _ | ||
lValue, cch) | lValue, cch) | ||
If lrc = ERROR_NONE Then vValue = lValue | If lrc = ERROR_NONE Then vValue = lValue | ||
Line 254: | Line 254: | ||
Const NOERROR = 0 | Const NOERROR = 0 | ||
Const MAX_LENGTH = 260 | Const MAX_LENGTH = 260 | ||
Const CSIDL_APPDATA = & | Const CSIDL_APPDATA = &H1A | ||
On Error GoTo Err_GetFolder | On Error GoTo Err_GetFolder | ||
Line 267: | Line 267: | ||
idlstr = SHGetPathFromIDList(ByVal IDL.mkid.cb, ByVal sPath) | idlstr = SHGetPathFromIDList(ByVal IDL.mkid.cb, ByVal sPath) | ||
If idlstr Then | If idlstr Then | ||
GetSpecialFolder = Left$(sPath, InStr(sPath, Chr$(0)) - 1) & | GetSpecialFolder = Left$(sPath, InStr(sPath, Chr$(0)) - 1) & "\" | ||
End If | End If | ||
End If | End If | ||
Line 275: | Line 275: | ||
Err_GetFolder: | Err_GetFolder: | ||
MsgBox "An Error was Encountered" & | MsgBox "An Error was Encountered" & Chr(13) & Err.Description, _ | ||
vbCritical Or vbOKOnly | vbCritical Or vbOKOnly | ||
Resume Exit_GetFolder | Resume Exit_GetFolder | ||
Line 298: | Line 298: | ||
' or it is empty, look for user profile Start-Up path. | ' or it is empty, look for user profile Start-Up path. | ||
If sPath = ERROR_BADKEY Or sPath = "" Or IsEmpty(sPath) Then | If sPath = ERROR_BADKEY Or sPath = "" Or IsEmpty(sPath) Then | ||
sPath = GetSpecialFolder() & | sPath = GetSpecialFolder() & "Microsoft\Word\Startup" | ||
End If | End If | ||
Line 315: | Line 315: | ||
"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "AppData") | "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "AppData") | ||
MsgBox "The folder is " & | MsgBox "The folder is " & datafolder & "\Microsoft\Word\Startup" | ||
</pre> | </pre> | ||
For more information about how to use the sample code in this article, click the article number below to view the article in the Microsoft Knowledge Base: | For more information about how to use the sample code in this article, click the article number below to view the article in the Microsoft Knowledge Base: |
Revision as of 12:32, 21 July 2020
Article ID: 210860
Article Last Modified on 10/11/2006
APPLIES TO
- Microsoft Word 2000 Standard Edition, when used with:
- Microsoft Windows 98 Standard Edition
- Microsoft Windows NT 4.0
This article was previously published under Q210860
SUMMARY
A driving goal of Office 2000 is to reduce total cost of software ownership (TCO) and comply with the ZAW (Zero Administration Windows) standard to make it easier and more cost-effective for organizations to deploy and manage application installations. ZAW standards emphasize writing as little to the registry as possible, and in the spirit of ZAW and customer requests, Office 2000 has significantly reduced adding information to the registry.
In keeping to these standards, Word 2000 (and Office 2000) will not write out the Startup-Path key to the registry when using the new Roaming User feature and/or User Profiles in Windows, unless the path is specifically changed by the user.
This article provides a method that you can use to obtain the current user's Startup folder path, which you can incorporate into an Office 2000 solution.
MORE INFORMATION
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements. The correct way to install a solution in Office 2000 is to use the SHGetSpecialFolderLocation Windows API function to return the current user application folder and append "Microsoft\Word\Startup" to it. The name of the folder is typically
C:\Windows\Application Data
-or-
C:\Windows\Profiles\user name
\Application Data
where user name
is a particular user name.
NOTE: Using the SHGetSpecialFolderLocation API may fail if the user manually changes the location of his or her Startup folder (using Tools/Options/File Locations) to a different location. The API returns the location of the current user's application folder with "Microsoft\Word\Startup" appended to it, and this may not be the correct location.
To determine whether the user has changed the location of the Startup folder, your application can first check the Microsoft Word registry. If the following Startup-Path registry entry exists, the user either changed the folder location or is not using User Profiles:
HKEY_CURRENT_USER\Software\Microsoft\Office\9.0\Word\Options\STARTUP-PATH
If this registry entry does not exist, you can use the SHGetSpecialFolderLocation API to return the current user's Startup folder location.
The following sample code demonstrates how to retrieve the Word Startup path in Microsoft Visual Basic or Microsoft Visual Basic for Applications.
Type the following code in the General Declarations section of a global module of your Visual Basic project.
NOTE: The following procedures require the following:
Microsoft Word 2000 or later
Microsoft Windows 98 or later
Microsoft Windows NT 4.0 or later
' ====== Begin General Declarations Module =========== ' ----Begin SHGetSpecialFolderLocation API Declarations---- ' Declare Public variables. Public Type ShortItemId cb As Long abID As Byte End Type Public Type ITEMIDLIST mkid As ShortItemId End Type ' Declare API functions. Public Declare Function SHGetPathFromIDList Lib "shell32.dll" _ (ByVal pidl As Long, ByVal pszPath As String) As Long Public Declare Function SHGetSpecialFolderLocation Lib _ "shell32.dll" (ByVal hwndOwner As Long, ByVal nFolder _ As Long, pidl As ITEMIDLIST) As Long ' ----End SHGetSpecialFolderLocation API Declarations---- ' ----Begin Get 32 Bit Registry Entry Value Declarations---- Const HKEY_CURRENT_USER = &H80000001 Const ERROR_SUCCESS = 0& Const REG_DWORD = 4 Const REG_BINARY = 3 Const REG_SZ = 1 Const REG_EXPAND_SZ = 2 ' Unicode nul terminated string Const ERROR_NONE = 0 Const ERROR_BADDB = 1 Const ERROR_BADKEY = 2 Const ERROR_CANTOPEN = 3 Const ERROR_CANTREAD = 4 Const ERROR_CANTWRITE = 5 Const ERROR_OUTOFMEMORY = 6 Const ERROR_ARENA_TRASHED = 7 Const ERROR_ACCESS_DENIED = 8 Const ERROR_INVALID_PARAMETERS = 87 Const ERROR_NO_MORE_ITEMS = 259 Const KEY_ALL_ACCESS = &H3F Const REG_OPTION_NON_VOLATILE = 0 Declare Function RegOpenKeyEx Lib "advapi32.dll" _ Alias "RegOpenKeyExA" (ByVal hKey As Long, _ ByVal lpSubKey As String, ByVal ulOptions As Long, _ ByVal samDesired As Long, phkResult As Long) As Long Declare Function RegCloseKey Lib "advapi32.dll" _ (ByVal hKey As Long) As Long Declare Function RegQueryValueExString Lib "advapi32.dll" Alias _ "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As _ String, ByVal lpReserved As Long, lpType As Long, ByVal lpData _ As String, lpcbData As Long) As Long Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias _ "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As _ String, ByVal lpReserved As Long, lpType As Long, lpData As _ Long, lpcbData As Long) As Long Declare Function RegQueryValueExNULL Lib "advapi32.dll" Alias _ "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As _ String, ByVal lpReserved As Long, lpType As Long, ByVal lpData _ As Long, lpcbData As Long) As Long Declare Function RegQueryValueEx Lib "advapi32.dll" Alias _ "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _ ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData _ As Long) As Long ' ----End Get 32 Bit Registry Entry Value Declarations---- ' ====== End General Declarations Module ===========
Public Function QueryValue(sKeyName As String, _ sValueName As String) ' This function, in conjunction with the QueryValueEx Function, ' will return a specified registry entry. Dim lRetVal As Long ' Result of the API functions. Dim hKey As Long ' Handle of opened key. Dim vValue As Variant ' Setting of queried value. lRetVal = RegOpenKeyEx(HKEY_CURRENT_USER, sKeyName, 0, _ KEY_ALL_ACCESS, hKey) lRetVal = QueryValueEx(hKey, sValueName, vValue) QueryValue = vValue RegCloseKey (hKey) End Function
Function QueryValueEx(ByVal lhKey As Long, ByVal szValueName As _ String, vValue As Variant) As Long ' This function, in conjunction with the QueryValue Function, ' will return a specified registry entry. Dim cch As Long Dim lrc As Long Dim lType As Long Dim lValue As Long Dim sValue As String On Error GoTo QueryValueExError ' Determine the size and type of data to be read. lrc = RegQueryValueExNULL(lhKey, szValueName, 0&, lType, 0&, cch) If lrc <> ERROR_NONE Then Error 5 Select Case lType ' For strings Case REG_SZ: sValue = String(cch, 0) lrc = RegQueryValueExString(lhKey, szValueName, 0&, lType, _ sValue, cch) If lrc = ERROR_NONE Then vValue = Left$(sValue, cch - 1) Else vValue = Empty End If Case REG_EXPAND_SZ: sValue = String(cch, 0) lrc = RegQueryValueExString(lhKey, szValueName, 0&, lType, _ sValue, cch) If lrc = ERROR_NONE Then vValue = Left$(sValue, cch - 1) Else vValue = Empty End If Case REG_DWORD: lrc = RegQueryValueExLong(lhKey, szValueName, 0&, lType, _ lValue, cch) If lrc = ERROR_NONE Then vValue = lValue Case Else 'All other data types not supported. lrc = -1 End Select QueryValueExExit: QueryValueEx = lrc Exit Function QueryValueExError: Resume QueryValueExExit End Function
Function GetSpecialFolder() As String ' This function returns the StartUp Folder Path found ' in the Current Users Profile. Dim idlstr As Long Dim sPath As String Dim IDL As ITEMIDLIST Const NOERROR = 0 Const MAX_LENGTH = 260 Const CSIDL_APPDATA = &H1A On Error GoTo Err_GetFolder ' Fill the idl structure with the specified folder item. idlstr = SHGetSpecialFolderLocation(0, CSIDL_APPDATA, IDL) If idlstr = NOERROR Then ' Get the path from the idl list, and return ' the folder with a slash at the end. sPath = Space$(MAX_LENGTH) idlstr = SHGetPathFromIDList(ByVal IDL.mkid.cb, ByVal sPath) If idlstr Then GetSpecialFolder = Left$(sPath, InStr(sPath, Chr$(0)) - 1) & "\" End If End If Exit_GetFolder: Exit Function Err_GetFolder: MsgBox "An Error was Encountered" & Chr(13) & Err.Description, _ vbCritical Or vbOKOnly Resume Exit_GetFolder End Function
NOTE: Run the following procedure to return the values from the functions QueryValue, QueryValueEx, and GetSpecialFolder.
Sub GetWordStartUpPath() Dim sKey As String Dim sVal As String Dim sPath As Variant ' Set Key and Value to lookup. sKey = "Software\Microsoft\Office\9.0\Word\Options" sVal = "STARTUP-PATH" ' Check for user-specified Start-Up Path. sPath = QueryValue(sKey, sVal) ' If the user-specified Start-Up Path does not exist ' or it is empty, look for user profile Start-Up path. If sPath = ERROR_BADKEY Or sPath = "" Or IsEmpty(sPath) Then sPath = GetSpecialFolder() & "Microsoft\Word\Startup" End If ' Display the VALID StartUp Folder path. MsgBox sPath End Sub
Note that if you are creating a solution within Word via Visual Basic for Applications, you can retrieve the current Startup path by using the following single command line:
MsgBox Options.DefaultFilePath(Path:=wdStartupPath)
NOTE: You can use the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders registry key to retrieve the application data folder and append "Microsoft\Word\Startup" to it, instead of using the preceding method. This method may fail on some systems, however, and has not been fully tested. To use this method, see the following code:
Dim datafolder As String datafolder = System.PrivateProfileString("", _ "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", "AppData") MsgBox "The folder is " & datafolder & "\Microsoft\Word\Startup"
For more information about how to use the sample code in this article, click the article number below to view the article in the Microsoft Knowledge Base:
212536 OFF2000: How to Run Sample Code from Knowledge Base Articles
REFERENCES
For additional information about using the registry APIs to save and retrieve a registry setting, click the article number below to view the article in the Microsoft Knowledge Base:
145679 HOWTO: Use the Registry API to Save and Retrieve Setting
For additional information about getting help with Visual Basic for Applications, click the article number below to view the article in the Microsoft Knowledge Base:
226118 OFF2000: Programming Resources for Visual Basic for Applications
Keywords: kbinfo KB210860