Important The guidelines outlined in this appendix are not required to comply with the Application Specification for Windows 2000, but are strongly encouraged to provide a better user experience.
A-1 Do not require a reboot for installation of your application on Windows 2000
A-2 Use SHGetFolderPath to determine special folder paths
A-3 Test your application under Terminal Services
A-4 Globalization
A-5 Localizability
A-6 Use 64-bit compatible data types
A-7 Additional Considerations for Cluster Service
A-8 Windows Management Instrumentation
A-9 Provide MMC snap-in for management tools
A-10 Expose a COM-based scripting model
A-11 Use COM+ for Distributed Applications
A-12 Run without NetBIOS in Windows 2000-only environment
Installation of your application should not require a reboot when you install it onto a freshly installed Windows 2000 system with no applications running, unless you are deploying any of the following as part of your install:
Generally, a reboot on Windows 2000 should not be necessary, even if applications are running. In the past a typical reason applications would reboot was because they were replacing a file that was in use at the time. However, on Windows 2000, these situations are greatly reduced by Windows File Protection (WFP).
WFP protects essential system files, so applications should not attempt to replace them. These files will be updated only via an operating system update package, instead of in a piecemeal fashion by individual applications.
In addition, applications that use the Windows Installer will be less likely to need a reboot. Windows Installer service will automatically check to see if other applications or service processes are using files that it is attempting to update. In these cases, Windows installer will prompt the user to shutdown the applications that are using those files. If the user does this, the application can install without a reboot. If the user does not shut down those applications, Windows Installer will prompt for a reboot.
Note Based on strong customer feedback, we recommend that you
DO NOT REQUIRE A REBOOT UNLESS IT IS ABSOLUTELY NECESSARY.
Whenever you access any of the special folders in the following list, your application should use the Win32 APIs to dynamically obtain the proper language-specific folder names. The preferred way to do this is using the SHGetFolderPath API with the appropriate CSIDL constant. This function behaves consistently across Windows 95, Windows 98, Windows NT 4.0, and Windows 2000. This API is redistributable via the SHFOLDER.DLL. Software vendors are encouraged to redistribute this component as much as possible to enable this support on Windows operating systems prior to Windows 2000. Windows 2000 includes this DLL as a protected system file and, as such, this DLL cannot be replaced on Windows 2000 or greater.
Note To ensure your application can run on Windows 9x, Windows NT 4.0 and Windows 2000, always link to the SHGetFolderPath implementation in SHFOLDER.DLL. Windows 2000 natively implements SHGetFolderPath in SHELL32.DLL, but other versions of Windows do not include SHGetFolderPath in SHELL32.DLL.
Standard Folder | CSIDL Constant Name |
Alternate Startup ([user], DBCS) | CSIDL_ALTSTARTUP |
Alternate Startup folder (All Users profile, DBCS) | CSIDL_COMMON_ALTSTARTUP |
Application Data ([user] profile) | CSIDL_APPDATA |
Application Data (All Users Profile) | CSIDL_COMMON_APPDATA |
Control Panel virtual folder | CSIDL_CONTROLS |
Cookies folder | CSIDL_COOKIES |
Desktop (namespace root) | CSIDL_DESKTOP |
Desktop folder ([user] profile) | CSIDL_DESKTOPDIRECTORY |
Desktop folder (All Users profile) | CSIDL_COMMON_DESKTOPDIRECTORY |
Favorites folder ([user] profile) | CSIDL_FAVORITES |
Favorites folder (All Users profile) | CSIDL_COMMON_FAVORITES |
Fonts virtual folder | CSIDL_FONTS |
History folder | CSIDL_HISTORY |
Internet Cache folder | CSIDL_INTERNET_CACHE |
Internet virtual folder | CSIDL_INTERNET |
Local (non-roaming) data repository for apps | CSIDL_LOCAL_APPDATA |
My Computer virtual folder | CSIDL_DRIVES |
My Pictures folder | CSIDL_MYPICTURES |
Network Neighborhood directory | CSIDL_NETHOOD |
Network Neighborhood root | CSIDL_NETWORK |
Personal folder ([user] profile) | CSIDL_PERSONAL |
Printers virtual folder | CSIDL_PRINTERS |
PrintHood folder ([user] profile) | CSIDL_PRINTHOOD |
Program Files folder | CSIDL_PROGRAM_FILES |
Program Files folder for x86 apps on Alpha systems | CSIDL_PROGRAM_FILESX86 |
Programs folder (under Start menu in [user] profile) | CSIDL_PROGRAMS |
Programs folder (under Start menu in All Users profile) | CSIDL_COMMON_PROGRAMS |
Recent folder ([user] profile) | CSIDL_RECENT |
Recycle Bin folder | CSIDL_BITBUCKET |
SendTo folder ([user] profile) | CSIDL_SENDTO |
Start menu ([user] profile) | CSIDL_STARTMENU |
Start menu (All Users profile) | CSIDL_COMMON_STARTMENU |
Startup folder ([user] profile) | CSIDL_STARTUP |
Startup folder (All Users profile) | CSIDL_COMMON_STARTUP |
System folder | CSIDL_SYSTEM |
System folder for x86 applications on Alpha systems | CSIDL_SYSTEMx86 |
Templates folder ([user] profile) | CSIDL_TEMPLATES |
User's profile folder | CSIDL_PROFILE |
Windows directory or SYSROOT | CSIDL_WINDOWS |
Many enterprise customers use Terminal Services to provide Windows 2000 applications to an array of desktop and mobile clients. Applications running under terminal services run only on the server. The Terminal Services client performs no local processing of applications. This means that in a terminal services environment, multiple instances of the same application may be running on the same machine at the same time, serving different users.
Because multiple users are running your application at the same time, it's critical to store application and user data properly. For more information, see Chapter 4, "Data and Settings Management" in the Desktop Application Specification.
In a Terminal Services environment, multiple instances of your application will be running on the same machine. Your application's .EXE and .DLL files should be written so multiple users can simultaneously run your application on the same machine. Considerations include:
Terminal Services manages objects on a per-client basis for you. You only need to implement object management if you do not want the operating system to do this for you. If a specific object should be available to all instances of the application, register the .DLL or .EXE that creates the object with the command register filename /system, or change the application to prefix the case-sensitive string Global\ (in C string form "Global\\") to the name of the object when it is created.
Optimizing Applications for Windows 2000 Terminal Services and Windows NT Server 4.0, Terminal Services Edition
www.microsoft.com/windows2000/library/planning/terminal/tsappdev.asp
Using and Understanding APIs for Terminal Services
www.microsoft.com/ntserver/terminalserver/techdetails/prodarch/api.asp
Using and Developing Applications Compatibility Scripts
www.microsoft.com/ntserver/terminalserver/techdetails/prodarch/AppCompSc.asp
Globalization is the practice of designing and implementing software that is not locale dependent, i.e., can accommodate any locale. In software design, a locale is defined as a set of user preferences associated with a user's language. A locale in Windows 2000 includes formats for date, time, currency and numbers; rules and tables for sorting and comparison; and tables of character classifications.
Other user preferences that a globalized application should accommodate include user-interface language, default font selection, language rules for use in spell checking and grammar, and input methods such as keyboard layouts and input method editors. See www.microsoft.com/globaldev/ for more details.
Guidelines for developing a globalized application include the following:
www.microsoft.com/globaldev/articles/singleunicode.asp
www.microsoft.com/globaldev/articles/multilang.asp
If you cannot use Unicode, you will need to implement features such as DBCS enabling, BiDi enabling, codepage switching, and text tagging. Guidelines related to this functionality are available at www.microsoft.com/globaldev/.
In contrast to globalization, localization is the process of modifying an application so that its user interface is in the language of the user. Well designed software can be localized to any of the languages supported by Windows 2000 without changes to the source code, i.e., without recompilation. In addition to the guidelines for globalization mentioned above, those for localizability include the following:
It is possible for developers to use a single source-code-base for their Win32-and Win64-based applications. Microsoft has added this support by introducing new data types in the Platform SDK for Windows 2000.
There are three classes of new data types: fixed-precision data types, pointer-precision types, and specific pointer-precision types. These types were added to the Windows environment (specifically, to-basetsd.h) to allow developers to prepare for 64-bit Windows well before its introduction. These new types were derived from the basic C-language integer and long types, so they work in existing code. You can use these data types in your code now, test your code as a Win32-based application, and recompile as a Win64-based application when 64-bit Windows is available
Fixed-precision data types are the same length in both Win32 and Win64 programming. To help you remember this, their precision is part of the name of the data type. The following are the fixed-precision data types:
Type | Definition |
DWORD32 | 32-bit unsigned integer |
DWORD64 | 64-bit unsigned integer |
INT32 | 32-bit signed integer |
INT64 | 64-bit signed integer |
LONG32 | 32-bit signed integer |
LONG64 | 64-bit signed integer |
UINT32 | Unsigned INT32 |
UINT64 | Unsigned INT64 |
ULONG32 | Unsigned LONG32 |
ULONG64 | Unsigned LONG64 |
As the pointer precision changes (that is, as it changes from 32 bits with Win32 code to 64 bits with Win64 code), these data types reflect the precision accordingly. Therefore, it is safe to cast a pointer to one of these types when performing pointer arithmetic; if the pointer precision is 64 bits, the type is 64 bits. The count types also reflect the maximum size to which a pointer can refer. The following are the pointer-precision and count types.
Type | Definition |
DWORD_PTR | Unsigned long type for pointer precision. |
HALF_PTR | Half the size of a pointer. Use within a structure that contains a pointer and two small fields. |
INT_PTR | Signed integral type for pointer precision. |
LONG_PTR | Signed long type for pointer precision. |
SIZE_T | The maximum number of bytes to which a pointer can refer. Use for a count that should span the full range of a pointer. |
SSIZE_T | Signed SIZE_T. |
UHALF_PTR | Unsigned HALF_PTR. |
UINT_PTR | Unsigned INT_PTR. |
ULONG_PTR | Unsigned LONG_PTR. |
There are also new pointer types that explicitly size the pointer. Be cautious when using pointers in 64-bit code. If you declare the pointer using a 32-bit type, the system creates the pointer by truncating a 64-bit pointer. (All pointers are 64 bits on a 64-bit platform.)
Type | Definition |
POINTER_32 | A 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer. |
POINTER_64 | A 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer.
Note It is not safe to assume the state of the high pointer bit. |
For more details, please see the Microsoft Platform SDK or visit
http://msdn.microsoft.com/library/psdk/buildapp/64bitwin_410z.htm.
This section identifies addition recommendations, above and beyond the core requirements for applications to support cluster service. These additional recommendations will improve performance and availability.
Server applications may store data in the system registry. The system registry is stored on a local system disk and is not shared or replicated among nodes in the cluster. Cluster Service can replicate system registry keys on behalf of a server application to guarantee that the application, when it moves from one node to another, can always see exactly the same data in the system registry.
To guarantee the consistency of the data, Cluster Service logs changes to the system registry keys, registered for replication, to one of the shared drives. When a server application fails over to another node, Cluster Service looks for any changes logged and rolls them forward to update the system registry on the current node.
Applications that use the system registry to store large data structures or update it frequently may affect the performance of the cluster and can experience long failover times because of the time needed to roll forward all logged updates.
To protect your application against software failures, such as application crashes, hangs, and slow response time, you should provide a resource DLL that extends Cluster Service capabilities to monitor and detect failures of your application.
To fully utilize the capacity of all nodes in the cluster, your application should support active/active mode where multiple instances of your application can coexist on the same cluster.
Active/Active failover and failback capability allows two separate instances of a resource type to be running on different nodes, each working with different data sets residing on different disks on the shared SCSI bus. (This means that, although the data isn't shared, the resource type is active on both nodes. By definition, there can only be one instance of a resource; however, there can be multiple instances of a resource type.) If the instance of the resource type fails on one node, that instance is moved or "failed over" to the next available node. For example, if your resource type is a database manager application, you can run a copy of the database manager resource type on each node. You can then define a particular database (db1) as a resource. With Active/Active capability, you can move db1 from node one to node two by telling the database manager on each node to release and acquire the database, as appropriate. This communication cannot happen with generic application or service resource types.
Downtime caused by planned operating system and application upgrades can be minimized by performing a rolling upgrade.
Rolling upgrade is the process of systematically upgrading each cluster node while the other nodes continue to provide service. Administrators perform rolling upgrades in stages, first by failing over all groups on a node, taking the node offline, upgrading the node, bringing it back online, failing back the groups to the node, and repeating this process on all other nodes. During a rolling upgrade, services are unavailable only for the time needed to move them from one node to another.
Cluster service supports rolling upgrades of the operating system. However, it's your responsibility to guarantee that your application will function properly during a rolling upgrade. It is also your responsibility to support rolling upgrades of your application.
Applications that support Active/Active mode allow installing multiple instances of the same resource type. Each instance of a resource uses system resources and contributes to the cluster service overhead. In addition, a maximum number of resources supported by a Cluster Service is limited to 1670.
If your application supports Active/Active mode and a cluster can be configured to have a large number of resources of your application type, it is recommended that you design your resource DLL to monitor and detect failures of all instances of your application using a single "combo" resource.
Once your application is under the Cluster Service control, it should not use Service Control Manager (SCM) APIs to start/stop services that were configured as cluster resources.
Service Control Manager and Cluster Service do not synchronize their operations. If you used SCM to stop a service, Cluster service would recognize it as a resource failure and would immediately restart the service.
Use GetNodeClusterState API to determine if the Cluster Service was installed and is running on a particular node.
Use ResUtilEnumResources to find if the particular service is under the control of Cluster Service.
Cluster-aware applications are perceived as difficult to install and manage. A cluster-ready application should come with a setup program that makes the application installation process as simple as possible and supports following scenarios:
Your cluster-aware application setup should perform following actions:
It should also meet the following requirements:
Your application should support remote administration.
Windows Management Instrumentation (WMI) is a key component of Microsoft's Windows management services. WMI provides a consistent and richly descriptive model of the configuration, status, and operational aspects of applications and systems.-based on the Distributed Management Task Force (DMTF) Common Information Model (CIM), WMI supports uniform system, device, and applications management in Windows operating systems.
WMI provides a unifying access mechanism to both standard and proprietary instrumentation methods, allowing applications to be managed both as discrete elements and as integrated and inter-related parts of a larger enterprise. By exposing a common access mechanism to all management instrumentation, WMI simplifies the task of developing well-integrated management applications.
Customers gain these benefits when products use WMI:
This section presents recommendations for creating WMI-compliant products. For the purposes of this section, the use of the terms application or product mean both user mode applications with a desktop graphical user interface and applications written as one or more services as well as managed products such as hardware devices.
WMI provides access to a wide variety of Windows system management information through the CIMV2 namespace, a Win32 extension of the CIM schema. Using WMI, an application has access to various management objects including Win32, Performance Monitor, Registry, Windows Installer service, Active Directory, and Event Log data.
If your product uses management functions and data provided by the system and/or other products, and that data is available in the CIMV2 namespace, your product should use WMI to access that management information rather than native APIs.
If your product has management functions and data that permit control or monitoring of your product by other management applications, it should be exposed through WMI according to the following recommendations (see the WMI SDK for development details and schema extension rules at http://msdn.microsoft.com/downloads/sdks/wmi/):
If your product extends the CIMV2 namespace, it should conform to the following guidelines:
The following classes and instances are created automatically when an application is installed using the Windows Installer service. Refer to the 'Settings Data' section below if you are modeling configuration information not created automatically by the Windows Installer Provider:
Note There may be multiple instances of the CIM_Setting class representing the possible configurations. The configuration information is settable via the CIM_Setting class. However, the current configuration information is typically stored in the Win32_ApplicationService instance.
The rules for extending the schema for settings (for example, any settable parameter defined for services, systems, applications or devices) are:
Note There may be multiple instances of the CIM_Setting class representing the possible configurations. The configuration information is settable via the CIM_Setting class. However, the current configuration information is typically stored in the CIM_ManagedSystemElement descendent instance.
The rules for extending the schema for statistics are:
Where the data is closely coupled with the Managed System Element and should be retrieved as native properties of the object, the data is placed as properties of the object itself (for example, packets transmitted or received on an Ethernet adapter).
Alternately, where the data may not always be available, is derived from existing data, or is not required to manage the object, it should be placed in a subclass of CIM_StatisticalInformation (for example, major, minor, or warning error counts on a device).
The rules for extending the schema to represent a device are:
Note There may be multiple instances of the CIM_Setting class representing the possible configurations. The configuration information is settable via the CIM_Setting class. However, the current configuration information is typically stored in the CIM_ManagedSystemElement descendent instance.
The rules for extending the schema to represent a computer system are:
The rules for extending the schema to represent physical configuration:
Microsoft is developing tools that will help to automate the verification process for compliance to the WMI recommendations. Please check http://msdn.microsoft.com/downloads/sdks/wmi/ for updated information. In the interim, we recommend using CIM Studio to verify the correctness of the schema design. CIM Studio is included with the WMI SDK. To use CIM Studio for pretesting, make sure you have:
MMC is an extensible, common console designed to integrate management tools and functions, and to present a common visualization environment for management applications. Management applications should be designed to take advantage of the features and support provided by MMC to enable them to present a common interface to the user.
Integrating the look and feel of management functionality in this way provides greater efficiency to administrators, who often combine a number of different management tools to solve a particular problem. Having these tools operate in a similar manner is helpful when managing an enterprise environment.
MMC also reduces the time to market for developers of management products by providing the foundation for the user interface of those applications. Developers can extend existing Console functionality or provide new functionality by the creation of one or more Console snap-ins. Snap-ins are the means by which new features and application behavior are added to the Console.
System administrators in corporate environments gain these benefits when your application uses MMC:
The simplest way to integrate your application with MMC is to add a context menu item to launch your standalone management tool from one or both of the core Windows 2000 snap-ins. Beyond this, tighter integration is achieved by writing a namespace extension to one of these snap-ins. The section below shows you how to create a context menu extension. Complete information on namespace extensions is available in the MMC SDK section of the Microsoft Platform SDK.
HKLM\Software\Microsoft\MMC\Nodetypes\
{476e6446-aaff-11d0-b944-00c04fd8d5b0}\Extensions/ContextMenu
If you extend the Users and Groups snap-in rather than the Computer Management snap-in, you will have to use the class GUID for the node you extend. The class GUID is found in the Directory Service section of the Microsoft Platform SDK. Use the Directory Service class registration tool found in this section of the SDK, and follow the steps listed earlier in this requirement to replace the Computer Management GUID with the correct one from the Directory Service section.
Microsoft recommends that you write an MMC namespace snap-in as an alternative to extending a context menu. A namespace snap-in offers the greatest value to an MMC user by taking full advantage of MMC features.
If you write a full namespace extension snap-in, follow the guidelines presented in the MMC snap-in author's guide. These guidelines ensure that snap-ins from different products operate consistently.
This guide can be found at www.microsoft.com/management/mmc/.
If the snap-in runs in a standalone mode, then load the snap-in in a user-mode Console and ensure the snap-in performs as expected.
If the snap-in extends Computer Management, then start the Computer Management console file from the Start menu and verify that your snap-in performs as expected.
If the snap-in extends the Users and Groups snap-in, then start the Users and Groups console file from the Start menu and verify that your snap-in performs as expected.
All applications should provide a COM-based scripting model, which will allow system administrators and integrators to access the functionality of the application or its configuration information programmatically. The scripting model should be accessible from the Windows Scripting Host and Active Server Pages.
By providing a scripting model, you enable your customers to:
Your server-based applications should be configured as COM+ applications to take advantage of the benefits provided by COM+. Use the Component Services snap-in for MMC to add your application to the COM+ Applications folder for the computer on which it is installed.
COM+ applications are created from one or more components that use COM+ services and are installed in the COM+ catalog.
COM+ defines a general purpose programming model for building distributed component-based server applications. Developers architect, design, and build their application servers as COM+ Components to be hosted in COM+ Applications that in turn leverage the Windows 2000 Component Services run-time (also known as the COM+ Services run-time). This execution environment provides the high scalability, robustness, and integrity traditionally associated only with high-end transaction processing systems. The COM+ execution environment automatically and transparently handles the complexities and details of transaction management, including: synchronization of shared resources, process and thread management, context management, role-based security and load balancing.
A COM+ application is a set of one or more in-process components installed in the COM+ catalog. COM+ applications are started on demand, without user intervention. The catalog can contain logon and security information for an application so that it can run although no user is logged on. System administrators can also customize security requirements for each application and thereby control access to it.
COM+ applications may be installed and controlled using standard user and Win32 APIs. Applications can be controlled both locally and remotely through the Component Services administrative tool, providing network administrators an easy and consistent way to control the application across the network.
The Platform SDK provides more information on building and deploying COM+ Applications.
It is possible to configure a Windows 2000-only environment to run without NetBIOS, and without the NetBIOS name service (i.e., the Windows Internet Name System-WINS).
Therefore, to ensure that applications can run in a Windows 2000-only environment:
Definitions of maximum computer name length and name validation APIs are discussed in the Active Directory Programmer's Guide.
For applications that run exclusively on the Windows 2000 platform:
For applications designed to run on all platforms that handle computer names in Unicode format, the WSALookupService family of APIs should be used for computer name resolution instead of gethostbyname.
To resolve domain names to Domain Controller names: