WEBSITE

IIS 7.0 : Runtime Web Server Extensibility (part 2) - Installing Modules

6/14/2012 4:45:21 PM

Installing Modules

The modules that comprise the IIS 7.0 feature set in Windows Vista or Windows Server 2008 can be installed via Windows Setup. Thanks to the modular architecture, Windows Setup enables very fine-grained installation of IIS 7.0 features—you can install most of the IIS 7.0 modules separately (along with all of their supporting configuration and administration features). You can also install the .NET Extensibility role service, which enables ASP.NET managed modules to run on IIS 7.0, or the ASP.NET role service, which also installs all of the of the ASP.NET managed modules and handlers to support fully functional ASP.NET applications. 

Windows Setup actually uses the same IIS 7.0 configuration APIs that you can use to manually install a third-party module on the server. In fact, Windows Setup uses Appcmd.exe, the IIS 7.0 command line tool, to perform module installation, which is just one of the ways that you can install modules on IIS 7.0. 

Installing Native Modules

To install a native module, it must be registered with the system.webServer/globalModules configuration section at the server level, in the ApplicationHost.config configuration file. Because only server administrators have access to this file, the installation of native modules requires Administrative privileges on the server. This is by design—allowing native code to execute in the IIS worker process is a potential security risk, and so Administrators must be sure to trust the source of the module.

The globalModules section contains an entry for each native module installed on the server, specifying the module name and the module image, which is the physical path to the module DLL.

        <globalModules>
            <add name="UriCacheModule"
image="%windir%\System32\inetsrv\cachuri.dll" />
            <add name="FileCacheModule"
image="%windir%\System32\inetsrv\cachfile.dll" />
            <add name="TokenCacheModule"
image="%windir%\System32\inetsrv\cachtokn.dll" />
            <add name="HttpCacheModule"
image="%windir%\System32\inetsrv\cachhttp.dll" />
            <add name="StaticCompressionModule"
image="%windir%\System32\inetsrv\compstat.dll" />
            <add name="DefaultDocumentModule"
image="%windir%\System32\inetsrv\defdoc.dll" />
            ...
        </globalModules>

The image attribute is an expanded string, which means that it can contain environment variables (as it does for modules installed by Windows Setup). This is a good practice to make sure that the ApplicationHost.config file remains portable and can be copied between servers and works on servers with different system drives.

Note

Native module DLLs should be located on the server’s local file system and not on remote network shares. This is because the server attempts to load them under the application pool identity and not the identity of the authenticated user or the configured virtual path (UNC) identity. This identity will not typically have access to network shares.

The act of registering a native module instructs IIS worker processes in all application pools to load the module DLL. The globalModules configuration section is also one of the few sections that cause IIS worker processes to recycle whenever changes are made. This means that you can install new modules, or uninstall existing modules, and IIS will automatically pick up those changes without needing to manually recycle application pools, restart IIS services, or run IISRESET.

Note

By adding the module to globalModules, you are instructing IIS worker processes to load the module DLL. This alone does not enable the module to run. To do that, you also need to enable the module on the server or for a particular application.

After the module is installed, it will be loaded by all IIS worker processes on the server. Unfortunately, IIS 7.0 does not enable native modules to be installed for a particular application pool, so there is no easy way to load a native module only into certain application pools and not into others.

Note

IIS 7.0 does provide a way to load native modules selectively into a specific application pool, by using the application pool name preconditions. Though loading native modules in this way is possible, you should not use this mechanism in most situations because of its management complexity.

However, loading the module alone is not sufficient to enable the module to execute. It also needs to be enabled by listing its name in the system.webServer/modules configuration section. This is an important distinction that serves to provide more flexible control over the enabled module set. Unlike the globalModules section, which can only be specified at the server level, the modules configuration section can be specified at the application level, such as in the application’s root Web.config. This enables each application to control the set of enabled modules that process requests to itself.

Typically, a native module is also enabled at the server level (in ApplicationHost.config) during its installation, which enables it for all applications on the server by default (except for applications that specifically remove it in their configuration). This is the case for most of the built-in native modules.

<modules>
    <add name="HttpCacheModule" />
    <add name="StaticCompressionModule" />
    <add name="DefaultDocumentModule" />
    ...
<modules>

Each native module is enabled simply by listing its name in the modules collection.

Inside Global Web Server Events

If you read the globalModules section carefully, you will notice that some modules, such as the TokenCacheModule, are listed there but yet are not listed in the modules list by default. Does this mean that this module is disabled by default? No, not entirely.

Native modules loaded inside the IIS worker process can participate in global server events, which are events that are not associated with request processing. These events enable native modules to extend certain server functionality at the worker process level, such as by providing the ability to cache logon tokens for improved performance.

Native modules that offer this kind of global functionality do not need to be listed in the modules list and are able to offer it by simply being loaded in the worker process. However, only modules listed in the modules list can provide request processing functionality.

Note

When the modules section changes, the IIS worker process does not need to recycle. Instead, it picks up the changes automatically and applies the resulting module set to subsequent requests. However, ASP.NET applications whose modules configuration changes will restart.

Uninstalling Native Modules

Caution

Before removing modules, you should consider the security and performance implications that the module removal will have on your server. 

To uninstall a native module, you need to remove the corresponding module entry from the globalModules list. This prevents the module from being loaded in IIS worker processes on the entire server. Removing the module from globalModules causes all IIS worker processes to gracefully recycle.

In addition, when the native module is removed from the globalModules list, references to it in the modules list also must be removed. Otherwise, all requests to the server or an application that enables the missing module will generate an "HTTP 500 – Internal Server Error" error until the module entry is removed. Typically, you should remove both the globalModules and modules entry for the module at the same time. However, if you do it in two separate steps, changing the modules section will not cause a worker process recycle—IIS will automatically pick up this change by recycling any affected applications. Be sure to make a configuration backup in case you need to restore the original configuration later.

When uninstalling a native module that is part of the IIS 7.0 feature set, you should instead uninstall the corresponding IIS Windows Setup component (Windows Vista) or Role Service (Windows Server 2008). Doing so has the benefit of removing the module binaries and related configuration components, as well as indicating that the corresponding feature is not installed to the Windows Setup infrastructure. The binaries remain stored in the OS installation cache, where they are inaccessible to anyone other than the OS TrustedInstaller subsystem. This ensures that you can re-install these modules later, and that any required patches are applied to these binaries even when the patches are not installed on your server.

Caution

You should not remove built-in IIS 7.0 modules manually. Use Windows Setup instead to uninstall the corresponding feature or role service.

When a custom module is uninstalled and all IIS worker processes have recycled, you can remove the module binary from the machine if necessary.

Installing Managed Modules

Managed modules developed using the ASP.NET APIs are not required to be installed globally on the server. Instead, they simply need to be enabled in configuration for the application where they are to be used, similar to classic ASP.NET applications in previous versions of IIS. This enables simple xcopy deployment of applications containing managed modules, since unlike native modules they do not require Administrative privileges to be deployed.

Needless to say, this makes managed modules very appealing in scenarios in which the application administrator does not have administrative privileges on the server, such as on shared hosting servers or departmental servers. Such applications can now deploy Web server features without contacting the server administrator to install a global and trusted component, which is often not possible. In these environments, the server administrator can constrain the execution of managed modules by limiting the trust of the ASP.NET applications. 

Note

Running managed modules requires installation of the ".NET Extensibility" Windows Setup component (Windows Vista) or Role Service (Windows Server 2008). This installs the ManagedEngine module that enables managed modules to run inside Integrated mode applications pools.

Installing the "ASP.NET" setup component/role service automatically installs the ".NET Extensibility" component and also adds the modules and handler mappings used by the ASP.NET framework. It also installs the classic ASP.NET handler mappings that enable application pools that use Classic integration mode to run ASP.NET using the legacy ASPNET_ISAPI.dll integration mechanism.

To install a managed module, the module simply needs to be added to the modules configuration section. This is the same section that enables installed native modules, except managed modules do not have to be listed in the globalModules configuration section. The modules section, therefore, provides a unified view of enabled modules, whether they are native or managed. Because this configuration section can be delegated down to the application level, each application can specify the complete set of enabled modules (managed or native) by using its modules configuration. Here is a more complete example of the modules configuration section at the server level after the ASP.NET feature is installed.

            <modules>
                <add name="HttpCacheModule" />
                <add name="StaticCompressionModule" />
                <add name="DefaultDocumentModule" />
                <add name="DirectoryListingModule" />
                ...
                <add name="FormsAuthentication"
type="System.Web.Security.FormsAuthenticationModule"
preCondition="managedHandler" />
                <add name="DefaultAuthentication"
type="System.Web.Security.DefaultAuthenticationModule"
preCondition="managedHandler" />
                <add name="RoleManager"
type="System.Web.Security.RoleManagerModule" preCondition="managedHandler"
/>
                 ...
            </modules>

As you can see, this section contains both native modules that are simply identified by the name attribute, and managed modules that also specify a type attribute. For each application, the server resolves the enabled modules by looking up the native modules’ names in the globalModules section and directly loading the specified .NET type for managed modules. The type is the fully qualified .NET type name that refers to the class that implements this module and resolves to an assembly that is packaged with the application or an assembly installed in the machine’s Global Assembly Cache (GAC).

Important


ASP.NET applications that define modules in the system.web/httpModules configuration section and ASP.NET handler mappings in the system.web/httpHandlers configuration section need to have their configurations migrated to the IIS system.webServer/modules and system.webServer/handlers configuration sections to operate correctly in Integrated mode. The server will generate a HTTP 500 error notifying you of this requirement if you attempt to run such an application in Integrated mode. You can migrate the application easily by using the Appcmd Migrate Config ApplicationPath command. 

Deploying Assemblies Containing Managed Modules

Managed modules are classes implemented inside .NET assemblies. To support delegated deployment of managed modules, the server provides several options, as shown in Table 3, for deploying the module assemblies so that they can be added both globally on the server and for a specific application only.

Table 3. Managed Modules and Deployment Options

Deployment Option

Assembly Location

Module Registration Location

Server

Global Assembly Cache (GAC)

Server level modules section in ApplicationHost.config

Application

Assembly in application’s /BIN directory

OR

Source code in application’s /App_Code directory

Application’s modules section in application root’s Web.config

Deploying the Module Assembly at the Server Level

If the module is to be installed globally for all applications on the server, it needs to be registered with the machine’s Global Assembly Cache (GAC). Before the managed assembly can be deployed to the GAC, it needs to be strongly signed by the developer (for more information on strongly signing .NET assemblies, see http://msdn2.microsoft.com/en-us/library/xc31ft41.aspx). In particular, Microsoft Visual Studio makes the signing process simple. Then, the managed assembly can be added to the GAC by running the following command.

gacutil.exe /if AssemblyPath

Note

The gacutil.exe command line tool is not available in the .NET Framework run-time installation that comes with the operating system, so you have to download the .NET Framework SDK to obtain it. After you obtain it, though, you can copy the tool to use on other machines.

After your assembly is added to the Global Assembly Cache, you can add any of the modules it contains to the server level modules section by specifying their type. This type name must be fully qualified; that is, it must contain the full namespace path to the class (for example, System.Web.Security.FormsAuthenticationModule). Because when it creates your module, ASP.NET needs to locate an assembly that contains this type, the assembly must either be listed in the system.web/compilation/assemblies configuration collection or included in the type name by using the strong name notation. Here is an example of a strong name for the built-in FormsAuthentication module.

System.Web.Security.FormsAuthenticationModule, System.Web, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=x86

Note

You can get the assembly part of the strong name by using the gacutil.exe tool you used earlier when you installed the assembly to the Global Assembly Cache. Run "gacutil.exe /l AssemblyName" to display the assembly’s strong name signature. You can omit all parts of the assembly’s strong name signature except for the assembly name, and ASP.NET will attempt to find the first matching assembly based on the attributes you do include.

You may wonder why the default module entries for ASP.NET modules do not specify the strong names and simply specify the fully qualified type names. This is because their parent assembly, System.Web.dll, is configured to be automatically preloaded by the ASP.NET applications (by being listed in the system.web/compilation/assemblies configuration collection in .NET Framework’s root Web.config). Thus, ASP.NET can locate the types of built-in ASP.NET modules by searching the preloaded assemblies, without having to specify the assembly signature in the module type string.

Deploying the Module Assembly with the Application

If the module is to be available in a specific application only, it can be xcopy-deployed with that application without registering anything globally on the server. In this case, the application owner can provide the module in two ways: as a compiled .NET assembly DLL in the /BIN subdirectory of the application root or as a source code file in the /App_Code subdirectory of the application root.

Note

It is not necessary to sign the assembly in the application’s /BIN subdirectory.

The /App_Code deployment model is more appropriate for development and test environments, because it enables editing of the module source code on the live server without recompiling the module DLL. The /BIN deployment model is recommended for production servers, because it does not require run-time compilation of the assembly and provides a more compact way to deploy large codebases than source code does.

Because the module type deployed inside the application is available only in the application, it can be used only in that application (unlike assemblies placed in the Global Assembly Cache, which are available to all applications on the server). To add the module, you simply need to add the fully qualified type into the modules configuration section in the application’s root Web.config file. For modules whose assemblies are in the /BIN directory, you can optionally specify the assembly name, although it is not necessary—ASP.NET by default preloads all /BIN assemblies. This is also true for modules that are deployed as source code to the /App_Code directory, because ASP.NET automatically compiles and loads it.

Packaging IIS 7.0 managed modules in the application is a powerful way to create self-contained applications that can be xcopy-deployed to a server and immediately function without globally installing any functionality on the server.


Uninstalling Managed Modules

Caution

Before removing modules, you should consider the security and performance implications that this action will have on your server. 

Unlike native modules, you can install managed modules simply by adding them to the modules list. Therefore, uninstalling managed modules is identical to disabling them and requires a single step.

Managed modules installed as part of ASP.NET installation cannot be individually uninstalled using Windows Setup (Windows Vista) or Server Manager (Windows Server 2008). So, if you need to remove any one of them, you have to do so by manually removing their entries from the modules section. Be sure to make a configuration backup in case you need to restore the original configuration later.

Understanding Module Preconditions

The modular architecture of IIS 7.0 relies heavily on controlling which modules are installed and enabled on the server and at the application level. Sometimes, making this determination based on static configuration is not sufficient, and the decision to use the module in a specific scenario must be made based on factors known only at run time. To support this functionality, IIS 7.0 introduces the concept of preconditions, which are configured conditions that the server evaluates at run time to determine whether a particular module should be used.

The following types of preconditions are supported:

  • Module load preconditions. These preconditions may be associated with each installed native module in the globalModules configuration section, and they determine whether a particular module is loaded by each worker process when it starts. If any of the preconditions do not evaluate to true, the module is not loaded in the worker process. These preconditions can also be used in the isapiFilters configuration section to control the loading of ISAPI filters.

  • Module enablement preconditions. These preconditions may be associated with each enabled module in the modules configuration section, and they determine whether the module is enabled for a particular application (or request). If any of the preconditions do not evaluate to true, the module does not run.

  • Handler mapping preconditions. These preconditions may be associated with each handler mapping in the handlers configuration section, and they determine whether this handler mapping is considered when mapping a request to handlers. If any of the preconditions do not evaluate to true, the handler mapping is ignored.

In each case, one or more precondition strings may be specified to allow the configuration entry to be selectively used in cases where all of the specified preconditions evaluate to true. If any of the preconditions fail, the module is not loaded or enabled, or the handler mapping is not considered, depending on the scenario in which the precondition is being used. Here is an example of ASP.NET setup using preconditions to load the "ManagedEngine" native module only in application pools that use Integrated mode, run Framework version 2.0, and are configured to execute in a 32-bit mode.

<globalModules>
  ...
  <add name="ManagedEngine"
image="%windir%\Microsoft.NET\Framework\v2.0.50727\webengine.dll"
preCondition="integratedMode,runtimeVersionv2.0,bitness32" />
</globalModules>

Table 4 lists the supported precondition strings and scenarios in which they can be used.

Table 4. Precondition Strings

Precondition

Applicable To

bitness32, bitness64

Matches the "bitness" of the application pool

globalModules, isapiFilters, modules, handlers

classicMode, integratedMode

Matches the configured managed pipeline mode of the application pool

globalModules, isapiFilters, modules, handlers

runtimeVersionv1.1, runtimeVersionv2.0

Matches the configured .NET run-time version of the application pool

globalModules, isapiFilters, modules, handlers

appPoolName=Name, appPoolName!=Name

Matches the application pool name; this precondition can be used to selectively load a native module into a specific application pool

globalModules, isapiFilters, modules, handlers

managedHandler

Matches requests to handler mappings with managed handlers

modules only

The bitness32 and bitness64 preconditions match the bitness of the worker process and can be used to selectively load modules in 32-bit or 64-bit application pools. In mixed 32-bit and 64-bit IIS environments, it may be necessary to load 32-bit native modules only in 32-bit application pools, because IIS will fail to load the 32-bit native DLLs into the 64-bit worker process. To help with this, the 32-bit native modules should configure the bitness32 precondition, which selectively loads them in 32-bit application pools only. 

The classicMode and integratedMode preconditions match the configured managedPipelineMode attribute of each application pool. Together with the runtimeVersion preconditions, they provide a foundation for the ASP.NET versioning in IIS 7.0 and also allow for selecting the right set of ASP.NET handler mappings based on the integration mode of the application pool. In application pools that either use the Classic ASP.NET integration mode or use a .NET version that does not support direct integration, IIS 7.0 uses legacy ISAPI-based handler mappings for ASP.NET. Both of these sets of handler mappings are configured at the server level, and they use the classicMode/integratedMode and runtimeVersion preconditions to automatically select the right set of handler mappings based on the application pool’s managed pipeline mode and Framework version.

You can use the applicationPoolName precondition to selectively load/enable modules and handler mappings in a particular application pool. An IIS 7.0 mechanism is provided to enable specific customer scenarios primarily on shared Web hosting servers. IIS 7.0 does not use it by default.

Finally, the managedHandler precondition enables modules to be enabled only for requests to ASP.NET handlers. For ASP.NET Integrated mode applications, IIS 7.0 enables managed modules to execute for all requests, whether or not they are mapped to ASP.NET handlers. However, by default, all ASP.NET modules use the managedHandler precondition to run only for requests to managed handlers. This also enables the ASP.NET appdomain creation to be delayed until the first request to an ASP.NET handler is made. This precondition can be removed from each module to allow it to run for all content types, regardless of whether they are managed or native. For example, to allow ASP.NET Forms-based authentication to occur for all content on the site, you need to remove the managedHandler precondition from the "FormsAuthentication" module.

Preconditions solve a number of key problems in IIS 7.0. However, they can also add management complexity, and if configured incorrectly, they can result in unintended behavior. The largest cause of precondition-related problems is due to preconditions preventing modules from being loaded/enabled or handler mappings from being used, resulting in missing functionality. Though the module or handler mapping may appear present, its precondition can be preventing it from being active. These types of problems may be hard to diagnose because missing functionality does not always manifest in errors.

Another common problem is precondition inconsistency, where related configuration is not preconditioned correctly and results in configuration errors. For example, if a native module has a bitness32 load precondition, but the corresponding enablement entry in the modules list does not, requests to 64-bit application pools will produce a "bad module" error because the module being enabled is not loaded. Likewise, if a handler mapping refers to a module whose enablement precondition in the modules list prevents it from being enabled, requests that are mapped to this handler mapping will encounter an error.

To avoid these problems, remember that preconditions primarily serve to prevent a module/handler mapping from being used in scenarios where it cannot function. Make sure that the preconditions do not restrict the module from being available in scenarios where it’s needed.

Also keep in mind the precondition relationships between the different configuration sections where they exist. Preconditions must get more restrictive as they go from module load preconditions, to module enablement preconditions, and finally to the handler mapping precondition for the module. For example, if the module load precondition in globalModules is "bitness32", the module enablement precondition for the corresponding entry in the modules section must at least contain that precondition. If the module is referenced in a handler mapping in the handlers configuration, the precondition of that entry must contain at least the precondition strings from the modules entry (which in turn contains at least the preconditions from globalModules entry).

Installing Modules for x64 Environments

When IIS 7.0 is installed on 64-bit versions of the operating system, it functions in native 64-bit mode by default. This means that all application pools create native 64-bit worker processes and load 64-bit IIS core engine components and modules. However, by allowing any of its application pools to use the 32-bit emulation mode called wow64, IIS 7.0 supports hosting both native 64-bit and 32-bit applications. Unlike IIS 6.0, which also provided the ability to use wow64, IIS 7.0 allows each application pool to configure this individually, enabling side by side hosting of native 64-bit and 32-bit applications on the same server.

Each application pool that has the enable32BitAppOnWin64 property set to true will create 32-bit worker processes and load the 32-bit version of the IIS core and modules. This is possible because IIS setup on 64-bit operating systems installs both 64-bit and 32-bit versions of all IIS components and modules—the native 64-bit versions go into the standard %windir%\System32\Inetsrv directory, and the 32-bit versions go into the %windir%\Syswow64\Inetsrv directory. At run time, when IIS tries to load modules located in the %windir%\System32\Inetsrv directory in a 32-bit wow64 worker process, the wow64 file system redirection feature automatically redirects the file access to the \Syswow64 directory where the 32-bit versions of the DLLs are located.

This mechanism enables IIS or third-party modules installed under the system32 directory to provide 32-bit versions under the \Syswow64 directory and then automatically load the correct version based on the "bitness" of the worker process.

However, the entire reason mixed 64-bit and 32-bit environments exist is that some functionality may not be available in native 64-bit flavors, requiring the worker process to operate in 32-bit mode. This is often needed for ASP applications that invoke in-process 32-bit COM components, 32-bit only ISAPI filters, or 32-bit only native modules. Likewise, some components may be available only in 64-bit flavors, and therefore they are not supported in 32-bit worker processes. To support such a scenario, you must be able to install native modules, ISAPI filters, and ISAPI extensions so that IIS never attempts to load a 32-bit component in a 64-bit worker process, and vice versa. IIS 7.0 provides this support via the bitness preconditions , which enable native modules, ISAPI filters, and handler mappings to indicate whether they are available only in 32-bit or 64-bit application pools.

For example, handler mappings that map requests to the 32-bit version of the ASP.NET ISAPI use the bitness32 precondition to insure that they are used only inside 32-bit worker processes.

<handlers accessPolicy="Read, Script">

  <add name="PageHandlerFactory-ISAPI-2.0" path="*.aspx"
verb="GET,HEAD,POST,DEBUG" modules="IsapiModule"
scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi
dll" preCondition="classicMode,runtimeVersionv2.0,bitness32"
responseBufferLimit="0" />
  ...
</handlers>

By default, the 64-bit version of the .NET Framework also registers an identical mapping to the 64-bit version of the aspnet_isapi.dll, which uses the bitness64 precondition so that it is selected only in 64-bit worker processes.

Using the bitness32 and bitness64 preconditions can therefore allow native modules, ISAPI filters, and ISAPI extensions specified in the handler mapping configuration to directly target 64-bit or 32-bit application pools, without using the file system redirection mechanism to provide both 32-bit and 64-bit flavors.

Other  
  •  Friends Reunited ...Reunited?
  •  Java EE 6 : Servlet Development and Deployment - Request forwarding and response redirection
  •  Java EE 6 : Servlet Development and Deployment - Processing HTML forms
  •  Separating BPM and SOA Processes : BPM-Oriented Disputes with TIBCO (part 2) - BusinessWorks Orchestration Processes & ActiveMatrix ESB Processes
  •  Separating BPM and SOA Processes : BPM-Oriented Disputes with TIBCO (part 1) - Architecture & iProcess Business Processes
  •  Separating BPM and SOA Processes : Disputes on the Model Stack
  •  Discover the @-SIGN : From Wine Fairs to Email Addresses
  •  IIS 7.0 : Techniques for Enabling Application Frameworks (part 2) - Deploying Frameworks That Use FastCGI
  •  IIS 7.0 : Techniques for Enabling Application Frameworks (part 1) - Enabling New Static File Extensions to Be Served & Deploying Frameworks Based on IIS 7.0 Native Modules
  •  Better Back Up : Mozy, Carbonite, Dropbox, Jungledisk & Livedrive
  •  
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8
    Visit movie_stars's profile on Pinterest.