天天看點

再分發 Windows Media 元件再分發 Windows Media 元件

再分發 Windows Media 元件

釋出日期: 12/14/2004 | 更新日期: 12/14/2004

Microsoft New Media Platforms Division

摘要

本文說明了将 Microsoft® Windows Media® runtime 元件包括在您的應用程式安裝中的過程和要求。将按以下順序讨論下列 Windows Media 技術:

Windows Media Format 9 Series SDK runtime (wmfdist.exe)
Windows Media Encoder 9 Series (WMEncoder.exe)
Windows Media Player 9 Series(MPSetup.exe、MPSetupXP.exe、wmppia.dll)
Windows Media Codecs (WM9Codecs.exe)
Primary Interop Assemblies
Windows Media Services 9 Series(wmstypelib.exe、wmspia.exe)
再分發 Windows Media 元件再分發 Windows Media 元件
本頁内容
再分發 Windows Media 元件再分發 Windows Media 元件
再分發和許可 Windows Media 元件
再分發 Windows Media 元件再分發 Windows Media 元件
再分發 Windows Media Format 9 Series 軟體
再分發 Windows Media 元件再分發 Windows Media 元件
再分發 Windows Media Encoder 9 Series 軟體
再分發 Windows Media 元件再分發 Windows Media 元件
再分發 Windows Media Player 9 Series 軟體
再分發 Windows Media 元件再分發 Windows Media 元件
Windows Media 編碼解碼器再分發
再分發 Windows Media 元件再分發 Windows Media 元件
關于主 Interop 程式集
再分發 Windows Media 元件再分發 Windows Media 元件
Windows Media Services 9 Series 軟體

再分發和許可 Windows Media 元件

您可以仔細查閱 Microsoft 網站 Windows Media 許可網頁上的 Windows Media® 許可指南。

有關其他的許可資訊,請參閱 MSDN 網站上的 Redistributing and Licensing Windows Media Components。

再分發 Windows Media 元件再分發 Windows Media 元件

傳回頁首

再分發 Windows Media Format 9 Series 軟體

将 Windows Media 軟體包括在某個應用程式安裝中的過程稱為再分發。Windows Media Format SDK 9 Series 包括了一個安裝程式包 (wmfdist.exe),該程式包可以包括在您的應用程式安裝中。安裝 Windows Media Format SDK 時,此分發程式包會複制到 SDK 安裝位置根目錄下的 \Redist 檔案夾中。

下面幾節将介紹将 Windows Media Format runtime 元件包括在您的應用程式安裝中的過程和資訊。

建立再分發安裝

1. 調用再分發程式包之前,請首先讓您的安裝例程安裝您的應用程式檔案,并進行所需的設定。
2. 安裝 WMFDist.exe。您可以使用 /Q:A 标志執行安靜的無人參與安裝,并在應用程式(例如:WMFDist.exe /Q:A )安裝期間不顯示再分發安裝的使用者界面。然後您的例程必須檢測結束時是否需要重新啟動重新啟動。

WMFdist.exe 指令行參數

将 WMFDist.exe 作為應用程式的一部分進行安裝時,管理者或開發人員可以通過使用下列指令,來控制安裝 UI 顯示和重新啟動重新啟動行為:

WMFdist.exe /Q:A
      

此指令指定無人參與安裝,并且不出現任何 UI 或警告。

注 下一節中的代碼示例說明了如何在程式包運作結束之後确定成功還是失敗,以及是否需要重新啟動。

檢測 WMFDist.exe 的安裝狀态

下面的代碼可用于 Windows Media Format SDK runtime 再分發或 Windows Media Player 再分發程式包。

安裝狀态将作為 HRESULT 存儲在下列位置:

HKCU, Software\Microsoft\MediaPlayer\Setup, REG_SZ, value InstallResult
      

HRESULT 值可用于确定安裝是否成功以及是否需要重新啟動。

下面的 C++ 示例代碼可包含在一個調用安裝應用程式中。此代碼會根據元件再分發程式包中 Windows Media 安裝寫入的 HRESULT 值,将 fSuccess 和 fRebootNeeded 變量設定為合适的 true 或 false。

#include <windows.h>
#include <stdio.h>
 
// If NS_S_REBOOT_REQUIRED is undefined, use 0xD2AF9.
#ifndef NS_S_REBOOT_REQUIRED
#define NS_S_REBOOT_REQUIRED       0xd2af9
#endif
 
int main( void )
{
    HKEY hKey = NULL;
    BOOL fSuccess = FALSE;
    BOOL fRebootNeeded = FALSE;
 
if( ERROR_SUCCESS == RegOpenKeyExA( 
                         HKEY_CURRENT_USER, 
                         "Software\\Microsoft\\MediaPlayer\\Setup", 
                         0, KEY_QUERY_VALUE, &hKey ))
    {
        char szResult[64];
        DWORD dwResult = sizeof( szResult );
 
if( ERROR_SUCCESS == RegQueryValueExA( 
                         hKey, "InstallResult", NULL, NULL, 
                         (LPBYTE)szResult, &dwResult ) )
        {
            sscanf( szResult, "%x", &dwResult );
            fSuccess = SUCCEEDED( dwResult );
            fRebootNeeded = ( NS_S_REBOOT_REQUIRED == dwResult );
        }
 
        RegCloseKey( hKey );
    }
 
    if( fSuccess )
    {
        printf( "Setup Succeeded..." );
        if( fRebootNeeded )
            printf( "A restart IS required...\n" );
        else
            printf( "A restart IS NOT required...\n" );
    }
    else
    {
        printf( "Setup Failed..." );
        if( fRebootNeeded )
            printf( "A restart IS required...\n" );
        else
            printf( "A restart IS NOT required...\n" );
    }
 
    return 0;
}

 
      

如果要将再分發程式包包括在您的應用程式中,則當您在安裝例程中調用該再分發程式包時,可以使用 /Q:A 标志。這樣會抑制使用者界面 (UI) 的顯示。因為 WMFdist.exe 程式包的設計意圖就是為了用于軟體再分發,是以該程式包會抑制自動重新啟動,不會通過使用者界面傳回或通知使用者重新啟動情況。請確定使用傳回系統資料庫的資訊來執行下列操作:

确定在運作 WMFdist.exe 之後計算機是否需要重新啟動。
處理需要重新啟動的情況,以及需要重新啟動時與最終使用者的通信。

下面的示例代碼可在您的安裝例程中用來以安靜模式運作再分發程式包,并在計算機必須重新啟動時通知您的安裝例程。

///
//
// MUST ADD:
//
// You must add "shlwapi.lib" to your project settings (link)
//
///

#include <windows.h>
#include <shlwapi.h>
#include <TCHAR.H>
#include <iostream>
using std::cout;
using std::endl;

#define MAX_TIMEOUT_MS 30 * 60 * 1000
#define TIME_INCREMENT 250

// Prototypes
BOOL GoInstallWMRedist( BOOL );
BOOL SystemNeedsReboot( void );

void main( void )
{
    GoInstallWMRedist( TRUE );

    cout << "Setup is complete...";

    if( SystemNeedsReboot() )
    {
        // Write some code here to ensure that your application will 
        // restart the computer, and delay dll registrations and so on 
        // until after the restart, where possible. For example, 
        // set a global flag for use by the application.
        cout <<  "A restart IS required..." << endl;
    }
    else
        cout <<  "A restart IS NOT required..." << endl;
    
}

///
// 
// Usage:
//
// Takes one parameter (BOOL)
//
// If you want to wait for completion, pass TRUE,
// else pass FALSE.
//
///
BOOL GoInstallWMRedist( BOOL fWaitForCompletion )
///
{
    STARTUPINFO StartUpInfo;
    PROCESS_INFORMATION ProcessInfo;

    StartUpInfo.cb = sizeof( StartUpInfo );
    StartUpInfo.lpReserved = NULL;
    StartUpInfo.dwFlags = 0;
    StartUpInfo.cbReserved2 = 0;
    StartUpInfo.lpReserved2 = NULL; 
    StartUpInfo.lpDesktop = NULL;
    StartUpInfo.lpTitle = NULL;
    StartUpInfo.dwX = 0;
    StartUpInfo.dwY = 0;
    StartUpInfo.dwXSize = 0;
    StartUpInfo.dwYSize = 0;
    StartUpInfo.dwXCountChars = 0;
    StartUpInfo.dwYCountChars = 0;
    StartUpInfo.dwFillAttribute = 0;
    StartUpInfo.dwFlags = 0;
    StartUpInfo.wShowWindow = 0;
    StartUpInfo.hStdInput = NULL;
    StartUpInfo.hStdOutput = NULL;
    StartUpInfo.hStdError = NULL;

    // Run the installer with the Quiet for All and Reboot:Never 
    // flags. The installation should be silent, and the setup routine  
    // will be notified whether the computer must be restarted.

    if( !CreateProcess( _T("c:\\temp\\WMFDist.exe"), 
            _T("c:\\temp\\WMFDist.exe /Q:A"), NULL, NULL, FALSE, 
            0, NULL, NULL, &StartUpInfo, &ProcessInfo ) )
    {
        DWORD myError = GetLastError();
        return( FALSE );
    }

    CloseHandle( ProcessInfo.hThread );

    if( fWaitForCompletion )
    {
        DWORD dwTimePassed = 0;
        while( TRUE )
        {
            if( WAIT_TIMEOUT != WaitForMultipleObjects( 
                  1, &ProcessInfo.hProcess, FALSE, TIME_INCREMENT ) )
                break;

            if( dwTimePassed > MAX_TIMEOUT_MS )
            {
                TerminateProcess( ProcessInfo.hProcess, E_FAIL );
                break;
            }
            dwTimePassed += TIME_INCREMENT;
        }
    }
    CloseHandle( ProcessInfo.hProcess);

    return( TRUE );
}

///
//
//  Used to determine whether the system should be restarted...
//
///
BOOL SystemNeedsReboot( void )
///
{
    BOOL fNeedExists = FALSE;
    OSVERSIONINFO osvi;

    osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
    GetVersionEx( &osvi );

    if( VER_PLATFORM_WIN32_NT != osvi.dwPlatformId )
    {
        TCHAR szIniPath[MAX_PATH];

        GetWindowsDirectory(szIniPath, 
                            sizeof(szIniPath)/sizeof(TCHAR));
        PathAddBackslash( szIniPath );
        _tcscat( szIniPath, _T("wininit.ini") );

        if( 0xFFFFFFFF != GetFileAttributes( szIniPath ) )
        {
            HFILE hFile;

            if( (hFile = 
                   _lopen(szIniPath,OF_READ|OF_SHARE_DENY_NONE))!= 
                                                      HFILE_ERROR )
            {
                fNeedExists = ( 0 != _llseek(hFile, 0L, FILE_END) );
                _lclose(hFile);
            }
        }
    }
    else
    {
        HKEY hKey = NULL;

        if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
            _T("System\\CurrentControlSet\\Control\\Session Manager"), 
             0, KEY_READ, &hKey ) )
        {
            if( ERROR_SUCCESS == RegQueryValueEx( hKey, 
                     _T("PendingFileRenameOperations"), 
                      NULL, NULL, NULL, NULL))
            {
                fNeedExists = TRUE;
            }

            RegCloseKey( hKey );
        }
    }

    return( fNeedExists );
}
      
再分發 Windows Media 元件再分發 Windows Media 元件

傳回頁首

再分發 Windows Media Encoder 9 Series 軟體

當您分發基于 Windows Media Encoder SDK 的應用程式時,必須通過在安裝中再分發 Windows Media Encoder,或者要求您的使用者自行安裝 Windows Media Encoder,将 Windows Media Encoder 軟體也包括在内。

如果您要再分發 Windows Media Encoder,則必須在安裝中包括并運作 WMEncoder.exe 安裝檔案。Microsoft 網站的下載下傳中心中提供有此檔案。如果您希望最終使用者自行安裝 Windows Media Encoder,則可以引導這些使用者通路此網站。

預設情況下,Windows Media Encoder 安裝在 C:\Program Files\Windows Media Components\Encoder 目錄中。

WMEncoder.exe 指令行參數

下面幾項内容顯示了 WMEncoder.exe 常用的指令行參數。

對于不帶 UI 的無人參與安裝:

wmencoder.exe /Q:A 
      

對于帶有進度條的無人參與安裝:

wmencoder.exe /Q 
      

檢測 Windows Media Encoder 9 Series

您可以通過搜尋系統資料庫的方式,确定所安裝的 Windows Media Encoder 的版本:

HKLM, Software\Microsoft\Windows Media\Encoder, "Version"
      

在該編碼器項下面,如果設定了 Version 字元串值,則可以放心地使用該字元串值作為所安裝的 Windows Media Encoder 的版本。

您可以使用下列系統資料庫項來确定 Windows Media Encoder 安裝目錄的位置:

HKLM, Software\Microsoft\Windows Media\Encoder, "InstallDir"
      
再分發 Windows Media 元件再分發 Windows Media 元件

傳回頁首

再分發 Windows Media Player 9 Series 軟體

在應用程式中檢測 Windows Media Player

您可以通過搜尋系統資料庫的方式,确定所安裝的 Windows Media Player 的版本。

HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components
      

對于 Windows Media Player 6.4,請檢視該項:

"{22d6f312-b0f6-11d0-94ab-0080c74c7e95}" 
      

對于 Windows Media Player 7、Windows Media Player for Windows® XP 或 Windows Media Player 9 Series,請檢視該項:

"{6BF52A52-394A-11d3-B153-00C04F79FAA6}" 
      

在上述任一項下面,如果 IsInstalledDWORD 值設定為 0x1,則可以放心地使用“Version”字元串值作為所安裝的 Windows Media Player 的版本。

MPSetup.exe 和 MPSetupXP.exe 指令行參數

下面是幾個常用的指令行參數。

對于不帶 UI、不需要重新啟動或沒有重新啟動提示的無人參與安裝:

mpsetup.exe /q:A /c:"setup_wm.exe /Q:A /R:N /P:#e"
      

這是一個标準的指令行,通常應該用于執行無人參與安裝。

防止媒體庫移植:

mpsetup.exe /q:A /R:N /c:"setup_wm.exe /NoMigrate /P:#e"
      

對安裝程式包進行緩存,用于以後的 Windows 更新移植:

mpsetup.exe /q:A /R:N /c:"setup_wm.exe /P:#e"
      

/P:#e 指定,在 Windows Media Player 安裝過程中應該對 Windows Media Player 安裝程式包進行緩存。在處理作業系統将來更新的所有指令行中,通常應該使用此參數。不應在指令行中包括 /P:#e 的唯一一種情況為,您知道目标系統永遠不會更新為更高版本的作業系統。例如,如果您正在 Windows 2000 上安裝 Windows Media Player 9 Series,并且該計算機在将來的某一天可能會更新為 Windows XP,則必須在指令行中使用 /P:#e。如果不使用此參數,則在 Windows XP 安裝之後,Windows Media Player 9 Series 檔案會被 Windows Media Player for Windows XP 的檔案所覆寫。

對于安靜模式:

/Q 
      

此參數用于不帶 UI 的無人參與安裝。

取消重新啟動提示:

/R:N 
      

此參數表示永遠不需要重新啟動,也不出現提示。如果您忽略此指令,則無論是否已經安裝該軟體,播放器都會在安裝結束時提示使用者重新啟動計算機。

建立嵌套的系統還原點:

/NestedRestore 
      

如果您的應用程式建立的系統還原點會将 Windows Media Player 還原點嵌套在應用程式還原點中,請使用此參數。

不允許建立系統還原點

/DisallowSystemRestore 
      

此标志會禁止系統還原點的建立。大多數情況下,對于一般的軟體再分發方案都不應該使用此标志。隻有當您可以代表最終使用者作出明确選擇,不支援 Windows Media Player 9 Series 檔案復原到該播放器的更早版本時,才應該使用此标志。此标志隻應在公司部署或者原始裝置制造商 (OEM) 安裝方案中使用。

注意

指令行參數區分大小寫。
取消重新啟動提示時,必須檢查 InstallResult 系統資料庫項,并處理調用安裝應用程式中的重新啟動通知。
Windows Media Player 9 Series 還會安裝 Windows Media Format runtime,是以無需将 Media Player 9 Series 分發程式包和 Windows Media Format Runtime 分發程式包同時包括在一個軟體再分發程式包中。例如,如果您在安裝中包括了 MPSetup.exe 或 MPSetupXP.exe,則無需包括 WMFdist.exe。

檢測 MPSetup.exe 和 MPSetupXP.exe 的安裝狀态

下面的代碼可用于 Windows Media Player 再分發程式包。

安裝狀态作為 HRESULT 存儲在下列位置:

HKCU, Software\Microsoft\MediaPlayer\Setup, REG_SZ, value InstallResult
      

HRESULT 值可用于确定安裝是否成功以及是否需要重新啟動。

下面的 C++ 示例代碼可包含在一個調用安裝應用程式中。此代碼會根據元件再分發程式包中 Windows Media 安裝寫入的 HRESULT 值,将 fSucess 和 fRebootNeeded 變量設定為合适的 true 或 false。

#include <windows.h>
#include <stdio.h>
 
// If NS_S_REBOOT_REQUIRED is undefined, use 0xD2AF9.
#ifndef NS_S_REBOOT_REQUIRED
#define NS_S_REBOOT_REQUIRED       0xd2af9
#endif
 
int main( void )
{
    HKEY hKey = NULL;
    BOOL fSuccess = FALSE;
    BOOL fRebootNeeded = FALSE;
 
if( ERROR_SUCCESS == RegOpenKeyExA( 
                         HKEY_CURRENT_USER, 
                         "Software\\Microsoft\\MediaPlayer\\Setup", 
                         0, KEY_QUERY_VALUE, &hKey ))
    {
        char szResult[64];
        DWORD dwResult = sizeof( szResult );
 
if( ERROR_SUCCESS == RegQueryValueExA( 
                         hKey, "InstallResult", NULL, NULL, 
                         (LPBYTE)szResult, &dwResult ) )
        {
            sscanf( szResult, "%x", &dwResult );
            fSuccess = SUCCEEDED( dwResult );
            fRebootNeeded = ( NS_S_REBOOT_REQUIRED == dwResult );
        }
 
        RegCloseKey( hKey );
    }
 
    if( fSuccess )
    {
        printf( "Setup Succeeded..." );
        if( fRebootNeeded )
            printf( "A restart IS required...\n" );
        else
            printf( "A restart IS NOT required...\n" );
    }
    else
    {
        printf( "Setup Failed..." );
        if( fRebootNeeded )
            printf( "A restart IS required...\n" );
        else
            printf( "A restart IS NOT required...\n" );
    }
 
    return 0;
}


      
再分發 Windows Media 元件再分發 Windows Media 元件

傳回頁首

Windows Media 編碼解碼器再分發

您可以更新 Windows Media Player 7 或 Windows Media Player for Windows XP,以使得這些軟體不必依賴 Internet 代碼自動下載下傳機制即可支援 Windows Media 9 Series 編碼解碼器。有一個用于此目的的編碼解碼器再分發程式包,名為 WM9Codecs.exe,該程式包可用于公司和軟體部署。

要在應用程式再分發安裝中使用這個程式包更新編碼解碼器,請使用下面的指令行将 WM9Codecs.exe 包括在内,并運作該程式包。

WM9Codecs.exe /Q:A 
      

這樣會啟動不帶 UI 的無人參與安裝。

注意

您必須使用 Windows Media Format runtime 再分發部分中說明的系統資料庫資訊,來檢查安裝成功狀态,并确定系統是否需要重新啟動來完成安裝。
如果在再分發安裝中包括了 Windows Media Player 9 Series 或 Windows Media Format runtime 分發程式包,則無需包括 Windows Media Codecs 安裝程式包。
再分發 Windows Media 元件再分發 Windows Media 元件

傳回頁首

關于主 Interop 程式集

使用 Microsoft Windows .NET 架構嵌入 Windows Media Player 控件的過程需要使用 Windows Media Player 主 interop 程式集 (PIA)。PIA 是一個獨特的架構程式集,其中包含了 COM 元件所實作的各種類型的類型定義(作為中繼資料)。隻有類型庫的釋出者才能生成真正的 PIA,該 PIA 将成為用于與基礎 COM 類型進行互動的正式類型定義的單元。

有關詳細資訊,請參閱 MSDN 網站上的 主 Interop 程式集 (PIA)。

與您的應用程式一起再分發主 Interop 程式集

主 Interop 程式集 (PIA) 是做為 Microsoft Windows .NET 架構應用程式的一部分再分發給最終使用者的。包含一個或多個 PIA 的應用程式的部署與任何基于 .NET 的應用程式一樣,不需要在使用者計算機上注冊每個相關的 COM 類型庫。

按照定義,PIA 總是由它們的釋出者進行簽名,以確定唯一性。按照它們所描述類型的唯一官方定義,您可以希望一些常用的 PIA 安裝在全局程式集緩存中,即使将這同一個程式集部署到應用程式目錄中也可如此。當全局程式集與本地程式集具有相同的供應商簽名時,公共語言運作庫總是會将您的應用程式指向該全局程式集緩存中的 PIA。在這種情況下,您的應用程式不會受到保護,會受供應商發起的版本更改的影響。最佳方法是始終安裝供應商提供的最新版本。然而,當您的應用程式需要上述保護時,則可以通過使用類型庫導入程式 (Tlbimp.exe)(而不是 PIA)來生成自己的 interop 程式集。

注冊用于應用程式開發的主 Interop 程式集

您必須使用程式集注冊工具 (RegAsm.exe) 和全局程式集緩存實用程式 (GacUtil.exe) 來注冊和安裝 Windows Media Player PIA。

要注冊 PIA,請在指令提示符下,鍵入:

regasm assemblyname 
      

在此指令中,assemblyname 為要注冊的程式集的檔案名。

下面的示例會注冊 wmppia.dll PIA。

regasm C:\WMSDK\WMPSDK9\redist\wmppia.dll
      

Regasm.exe 在與原始類型庫相同的系統資料庫項下面添加一個用于該 PIA 的系統資料庫項。

注冊了該 PIA 之後,使用全局程式集緩存實用程式将其安裝到全局程式集緩存 (GAC) 中。

要将 PIA 安裝到 GAC 中,請在指令提示符下,鍵入:

Gacutil /i assemblyname
      

在此指令中,assemblyname 為要安裝的程式集的檔案名。

下面的示例會在 GAC 中安裝 Windows Media Player PIA。

Gacutil /i C:\WMSDK\WMPSDK9\redist\wmppia.dll
      

注您應該在計算機中搜尋 RegAsm.exe 和 Gacutil.exe。通常這兩個程式位于 %windir%\Microsoft.NET\Framework\v1.0.xxxx 中(其中 xxxx 為您正在使用的 Windows .NET 架構的版本的内部版本号)或者您在其中安裝開發環境的 \FrameworkSDK\Bin 檔案夾中。

包含 Windows Media Player SDK 完整安裝所包含的 C# 示例應用程式的檔案夾還包含了一個名為 regpiagac.vbs 的腳本檔案。此實用程式可使得注冊 PIA 并将其添加到 GAC 中的過程變得十分簡單。輕按兩下該檔案并在出現提示時提供正确的路徑,即可完成該過程。如果您使用預設安裝路徑安裝了 Windows Media Player SDK 和 Visual Studio .NET,則隻需更改驅動器盤符。如果沒有使用預設路徑安裝這些産品,則可能會發生非預期的結果。

再分發 Windows Media 元件再分發 Windows Media 元件

傳回頁首

Windows Media Services 9 Series 軟體

Windows Media Services 9 Series 包含了下面兩個可再分發的元件,這兩個元件可在與 Windows Media Services 互動的軟體應用程式開發中使用。

WMSServerTypeLib.dll
microsoft.windowsmediaservices.dll

這兩個檔案可從 Microsoft Platform SDK 通過 Windows Media Services 9 Series 元件安裝選項獲得。安裝 Microsoft Platform SDK 會同時授予開發人員再分發這兩個檔案的權利。這兩個檔案位于 Microsoft Windows Platform SDK 安裝根檔案夾下的 \include 目錄中。預設情況下,該檔案夾為 C:\Program Files\Microsoft SDK\include。預設情況下,許可條款位于 Microsoft SDK\License 檔案夾中。