共用方式為


如何稽核 Visual C++ Runtime 版本使用量

Microsoft Visual C++ 可轉散發套件和 Visual Studio C++ 執行階段(統稱為「VC Runtime」)是許多應用程式的重要元件。 在您的網路上,機器可能仍在執行安裝並使用 VC 執行時間不支援版本的應用程式。 您可以使用 NTFS 檔案稽核來識別這類使用情況,以便將使用支援的 VC 執行時間版本的應用程式取代掉那些應用程式。 本指南會逐步引導您設定NTFS檔案稽核、提供疑難解答秘訣,並醒目提示定期稽核的優點。

如需不再支援之 VC 執行階段版本的詳細資訊,請參閱 Microsoft Visual C++ 最新支援的可再發行套件下載

啟用NTFS檔案稽核以判斷 VC 執行時間使用量

本指南提供手動啟用NTFS檔案稽核和檢閱稽核事件的步驟,以判斷哪些應用程式呼叫不支援的 VC 執行時間版本。 因為應用程式可以使用數個檔案,本指南也會示範如何使用PowerShell的 Get-AclSet-Acl Cmdlet 來更新稽核許可權。 如需如何設定檔案審核策略的詳細資訊,請參閱 在檔案或資料夾上套用基本審核策略

在系統上手動啟用物件存取稽核

啟用檔案層級稽核之前,必須先啟用物件存取:

  1. 按下 Windows + 開啟 [R,以開啟 [執行 ] 對話框。 然後輸入 gpedit.msc,然後按 Enter
  2. 瀏覽至 [計算機設定]>[Windows 設定]>[安全性設定]>[進階審核策略組態]>[系統審核策略]>[物件存取]
  3. 按兩下 稽核檔案系統。 在 [稽核文件系統屬性] 對話框中,選取 [[設定下列稽核事件]>[成功]>[確定]
  4. 關閉 本地組原則編輯器

或者,您可以使用 auditpol.exe 來啟用物件存取:

  1. 使用 AuditPol.exe /get /category:"Object Access"列出命令列中的目前設定。
  2. 使用 AuditPol.exe /set /category:"Object Access" /subcategory:"File System" /success:enable啟用物件存取。

在檔案上手動啟用稽核

若要監視存取 VC 執行時間檔案的進程,請在 VC 執行時間檔案上啟用稽核:

  1. 以滑鼠右鍵按下您要稽核的檔案,選取 [屬性] ,然後選取 [安全性] 索引卷標。如需尋找已安裝 VC 執行時間檔案的詳細資訊,請參閱 VC 執行時間安裝的位置。
  2. 選取 [進階]。
  3. 在 [進階安全性設定] 對話框中,選取 [稽核] 索引卷標,然後選取 [繼續]。
  4. 若要新增稽核規則,請選取 [[新增]。 在 [稽核專案] 對話框中,選取主體,然後輸入您想要新增的使用者或群組名稱,例如 (所有人),然後選取 確定
  5. 在 [類型]中,請確保選取的是 [成功]
  6. 選擇 顯示進階權限>清除全部>瀏覽資料夾/執行檔案>確認
  7. 稽核 項目中現在應該會有符合您所選擇的條件的新的數據列。 選取 [確定]
  8. 在 [屬性 對話框] 中,選取 [確定]。

現在已為檔案啟用稽核規則。

手動檢閱稽核記錄

NTFS 檔案稽核會對每一個具備稽核權限且被程序存取的檔案產生 「事件 4663:嘗試存取物件」

  1. 按下 [Windows + ] 將開啟 [執行 R] 開啟 [事件查看器]。 然後輸入 eventvwr.msc,然後按 Enter
  2. 事件查看器 中,展開 Windows 記錄>,然後導航至 安全性 記錄。 結果窗格會列出安全性事件。
  3. 在 [動作] 窗格中選擇 [篩選目前記錄...] 來尋找稽核事件。 請將事件範圍縮小至 事件 ID 4663(文件系統類別的稽核成功),方法是將 4663 輸入到[包含/排除事件 ID]文本框中。

如需檔案存取稽核事件 4663 的範例,請參閱 “4663(S):嘗試存取物件。”

使用 PowerShell 稽核 VC 運行時間使用量

在概觀中,使用 PowerShell 更新檔案稽核許可權會遵循下列步驟:

  1. 請定義文件系統稽核規則 以套用至檔案。
  2. 使用 Get-Acl取得檔案的安全性描述元。
  3. 將稽核規則 套用至安全性描述元。
  4. 使用 Set-Acl在源檔上套用更新的安全性描述元。
  5. 使用 Get-WinEvent檢視檔案存取稽核事件 4663 記錄。

PowerShell:審核已不支援的 VC 執行階段檔案

下列 PowerShell 程式代碼可讓您稽核不再支援的已安裝的 VC 執行時間檔案。

function Get-AuditRuleForFile {
    $auditRuleArguments =   'Everyone'              <# identity #>,
                            'ExecuteFile, Traverse' <# fileSystemRights #>,
                            'Success'               <# flags #>
    $auditRule = New-Object System.Security.AccessControl.FileSystemAuditRule($auditRuleArguments)

    return $auditRule
}

function Set-FileAuditRule {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$file,
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [System.Security.AccessControl.FileSystemAuditRule]$auditRule
    )

    $existingAcl = Get-Acl -Path $file
    $existingAcl.AddAuditRule($auditRule) | Out-Null
    Set-Acl -Path $file -AclObject $existingAcl
}

$newAuditRule = Get-AuditRuleForFile

# Visual Studio Redistributable for 2005 (VC++ 8.0) and 2008 (VC++ 9.0)
Get-ChildItem "$ENV:SystemRoot\WinSxS\Fusion" -filter '*.dll' -ErrorAction SilentlyContinue -Recurse |
Where-Object FullName -IMatch 'microsoft\.vc[89]0' |
ForEach-Object {
    Set-FileAuditRule $_.FullName $newAuditRule
}

# Visual Studio Redistributable for 2010 (VC++ 10.0), 2012 (VC++ 11.0) and 2013 (VC++ 12.0)
$languageCodes = 'chs|cht|deu|enu|esn|fra|ita|jpn|kor|rus'
$versions = '(1[012]0)'
$regex = "^((atl|msvc[pr]|vcamp|vccorlib|vcomp)$versions|mfc$versions(u|$languageCodes)?|mfcm$versions(u)?)\.dll$"
Get-ChildItem "$ENV:SystemRoot\SysWOW64","$ENV:SystemRoot\System32" -filter '*.dll' |
Where-Object Name -imatch $regex |
ForEach-Object {
    Set-FileAuditRule $_.FullName $newAuditRule
}

PowerShell:檢視檔案稽核事件

PowerShell 提供 Get-WinEvent 來取得各種事件記錄的事件記錄,如下列 PowerShell 程式代碼所示,列出過去 24 小時內的所有稽核事件 4663 記錄:

function Get-AuditEntries {
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [System.DateTime]$oldestTime
    )
    Get-WinEvent -FilterHashtable @{LogName='Security';Id=4663;StartTime=(Get-Date $oldestTime)} |
    ForEach-Object {
        $record = [ordered]@{}
        $record['TimeCreated'] = $_.TimeCreated
        $accessName = ($_.Message |
            Select-String -Pattern "Accesses:[\t\s]+(?<Accesses>.+)").Matches.Groups[1]
        ([xml]$_.ToXML()).Event.EventData.ChildNodes |
        ForEach-Object -Begin {
            $record[$accessName.Name]=$accessName.Value.Trim()
        } -Process {
            $record[$_.Name] = $_.'#text'
        }
        [PSCustomObject]$record
    } |
    Where-Object { $_.ObjectName -imatch '\.dll$'}
}

Get-AuditEntries -oldestTime (Get-Date).AddHours(-24)
TimeCreated : 11/20/2024 5:00:11 AM
Accesses : Execute/Traverse
SubjectUserSid : \*\*\*\*\*
SubjectUserName : \*\*\*\*\*
SubjectDomainName : WORKGROUP
SubjectLogonId : \*\*\*\*\*
ObjectServer : Security
ObjectType : File
ObjectName : C:\\Windows\\WinSxS\\amd64\_microsoft.vc90.crt\_1fc8b3b9a1e18e3b\_9.0.30729.9635\_none\_08e2c157a83ed5da\\msvcr90.dll
HandleId : 0x93c
AccessList : %%4421
AccessMask : 0x20
ProcessId : 0x24d4
ProcessName : C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe
ResourceAttributes : S:AI

稽核 VC 運行時間使用量之後的後續步驟

在您判斷哪些進程使用 VC 執行時間檔案,或哪些應用程式已安裝 VC 可轉散發套件之後,請卸載這些應用程式,或將它們升級至不相依於不支援的 VC 運行時間的較新版本。

有些 Microsoft 應用程式需要舊版的 VC 執行環境。 如需詳細資訊,請參閱 Visual C++ 再發行套件及執行階段庫常見問題 | Microsoft Learn

Visual C++ 運行時安裝位置

以下是每個版本的 VC 執行階段安裝位置:

Visual Studio 版本 安裝位置
Visual Studio 2013 (VC++ 12.0) %SystemRoot%\\System32, %SystemRoot%\\SysWOW64
Visual Studio 2012 (VC++ 11.0) %SystemRoot%\\System32, %SystemRoot%\\SysWOW64
Visual Studio 2010 (VC++ 10.0) %SystemRoot%\\System32, %SystemRoot%\\SysWOW64
Visual Studio 2008 (VC++ 9.0) %SystemRoot%\\WinSxS\\Fusion
Visual Studio 2005 (VC++ 8.0) %SystemRoot%\\WinSxS\\Fusion

另請參閱

重新發佈 Visual C++ 檔案
最新支援的 Visual C++ 下載
生命週期常見問題 - Visual C++ 可再發行套件和執行階段庫
Visual Studio 版本 之間的 C++二進制相容性