Skip to content

Additional Helpers

Calvindd2f edited this page Jan 14, 2026 · 1 revision

Additional Helpers

Relevant source files

The following files were used as context for generating this wiki page:

This page documents the remaining specialized helper classes in the OfficeScrubNative.dll library that support Office cleanup operations. These classes handle GUID transformations, shell integration, COM type library cleanup, license management, and Windows service operations.

For the core helper classes (RegistryHelper, FileHelper, ProcessHelper, WindowsInstallerHelper), see pages 4.3.1, 4.3.2, 4.3.3, and 4.3.4. For the central coordinator that uses these helpers, see OfficeScrubOrchestrator.


Helper Class Architecture

The following diagram shows how the additional helper classes fit into the overall orchestrator architecture:

graph TB
    Orchestrator["OfficeScrubOrchestrator"]
    
    subgraph "Additional Helpers"
        GH["GuidHelper<br/>(static utility)"]
        SH["ShellHelper"]
        TLH["TypeLibHelper"]
        LH["LicenseHelper"]
        SVH["ServiceHelper"]
    end
    
    subgraph "Core Helpers"
        RH["RegistryHelper"]
        FH["FileHelper"]
    end
    
    Orchestrator --> SH
    Orchestrator --> TLH
    Orchestrator --> LH
    Orchestrator --> SVH
    
    TLH --> RH
    TLH --> GH
    LH --> FH
    
    WindowsInstallerHelper["WindowsInstallerHelper"] --> GH
    
    style GH fill:#f9f9f9
    style SH fill:#f9f9f9
    style TLH fill:#f9f9f9
    style LH fill:#f9f9f9
    style SVH fill:#f9f9f9
Loading

Sources: OfficeScrubC2R-Native.cs:1349-1405, docs/memory-bank/structure.md:60-79


GuidHelper

GuidHelper is a static utility class that provides GUID transformation methods for converting between different GUID formats used by Windows Installer metadata.

GUID Format Overview

Format Length Example Usage
Expanded 38 chars {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} Standard format
Compressed 32 chars XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Registry key names
Encoded 20 chars XXXXXXXXXXXXXXXXXXXX Base85 encoding in multi-string values

GUID Transformation Pipeline

flowchart LR
    subgraph "Input Formats"
        Expanded["{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}<br/>Expanded GUID<br/>38 characters"]
        Compressed["XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br/>Compressed GUID<br/>32 characters"]
        Encoded["XXXXXXXXXXXXXXXXXXXX<br/>Encoded GUID<br/>20 characters Base85"]
    end
    
    subgraph "GuidHelper Methods"
        GetExpanded["GetExpandedGuid()<br/>Decompress + Format"]
        GetCompressed["GetCompressedGuid()<br/>Remove Dashes + Reorder"]
        GetDecoded["GetDecodedGuid()<br/>Base85 Decode"]
    end
    
    subgraph "Output Formats"
        OutExpanded["Standard GUID Format<br/>{...}"]
        OutCompressed["Registry Key Format"]
        OutDecoded["Standard GUID Format<br/>{...}"]
    end
    
    Compressed --> GetExpanded
    GetExpanded --> OutExpanded
    
    Expanded --> GetCompressed
    GetCompressed --> OutCompressed
    
    Encoded --> GetDecoded
    GetDecoded --> OutDecoded
Loading

Sources: OfficeScrubC2R-Native.cs:169-328

Methods

GetExpandedGuid

Converts a 32-character compressed GUID (used in registry keys) to standard 38-character format with braces and dashes.

public static string GetExpandedGuid(string compressedGuid)

Algorithm:

  1. Validate input length is exactly 32 characters
  2. Reverse byte order in first three sections (8-4-4 pattern)
  3. Swap byte pairs in last two sections
  4. Add braces and dashes

Example:

  • Input: D0DF45CD98B1FC4E8821FBB563E5BB89
  • Output: {DC54FDD0-1B89-4ECF-8821-FBB563E5BB89}

Sources: OfficeScrubC2R-Native.cs:173-214

GetCompressedGuid

Converts a standard 38-character GUID to 32-character compressed format for registry key names.

public static string GetCompressedGuid(string expandedGuid)

Algorithm:

  1. Remove braces and split on dashes
  2. Reverse byte order in first three sections
  3. Swap byte pairs in last two sections
  4. Concatenate into 32-character string

Sources: OfficeScrubC2R-Native.cs:216-253

GetDecodedGuid

Decodes a 20-character Base85-encoded GUID used in Windows Installer published components.

public static bool GetDecodedGuid(string encodedGuid, out string decodedGuid)

Algorithm:

  1. Validate input length is exactly 20 characters
  2. Process 5 characters at a time (Base85 groups)
  3. Use static decode table for character-to-value mapping
  4. Convert each group to 8 hexadecimal digits
  5. Rearrange sections to standard GUID format

Base85 Decode Table: The method uses a pre-computed 128-byte lookup table for ASCII-to-value translation, supporting characters: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~`

Sources: OfficeScrubC2R-Native.cs:255-320

Usage Example

sequenceDiagram
    participant WIH as WindowsInstallerHelper
    participant GH as GuidHelper
    participant RH as RegistryHelper
    
    WIH->>RH: EnumerateKeys("UpgradeCodes")
    RH-->>WIH: ["D0DF45CD...", "AB12CD34..."]
    
    loop For each compressed key
        WIH->>GH: GetExpandedGuid("D0DF45CD...")
        GH-->>WIH: "{DC54FDD0-...}"
        WIH->>WIH: shouldDelete(guid)
        alt Should Delete
            WIH->>RH: DeleteKey(path + key)
        end
    end
Loading

Sources: OfficeScrubC2R-Native.cs:989-1011, OfficeScrubC2R-Native.cs:1069-1127


ShellHelper

ShellHelper handles Windows shell integration operations, including unpinning shortcuts from the taskbar and Start menu, and restarting Windows Explorer.

Class Overview

classDiagram
    class ShellHelper {
        +UnpinFromTaskbar(string shortcutPath) bool
        +UnpinFromStartMenu(string shortcutPath) bool
        +RestartExplorer() void
    }
    
    class ShellApplication {
        <<COM Object>>
        +NameSpace(string path) Folder
    }
    
    class FolderItem {
        <<COM Object>>
        +Verbs() VerbCollection
    }
    
    ShellHelper ..> ShellApplication : uses via reflection
    ShellApplication --> FolderItem : returns
Loading

Sources: OfficeScrubC2R-Native.cs:864-974

Methods

UnpinFromTaskbar

Removes a pinned shortcut from the Windows taskbar using the shell verb system.

public bool UnpinFromTaskbar(string shortcutPath)

Process:

  1. Verify shortcut file exists
  2. Create Shell.Application COM object via reflection
  3. Navigate to shortcut's parent folder
  4. Enumerate shell verbs for the item
  5. Execute "unpin from taskbar" verb (localized)

Localization Support: The method detects and executes the unpin verb in multiple languages:

Language Verb Pattern
English unpin from taskbar
German von taskleiste lösen
French détacher de la barre des tâches
Spanish desanclar de la barra de tareas
Swedish ta bort från aktivitetsfältet
Danish frigør fra proceslinje
Czech odepnout z hlavního panelu
Dutch van de taakbalk losmaken
Finnish poista kiinnitys tehtäväpalkista
Italian rimuovi dalla barra delle applicazioni

Sources: OfficeScrubC2R-Native.cs:866-907

UnpinFromStartMenu

Removes a pinned shortcut from the Windows Start menu.

public bool UnpinFromStartMenu(string shortcutPath)

Process: Similar to UnpinFromTaskbar, but targets the Start menu verb patterns:

  • English: unpin from start
  • German: vom startmenü lösen
  • French: détacher du menu démarrer
  • Spanish: desanclar del menú inicio
  • Czech: odepnout z nabídky start
  • And others...

Sources: OfficeScrubC2R-Native.cs:909-947

RestartExplorer

Terminates all Windows Explorer processes and restarts a new instance.

public void RestartExplorer()

Process:

  1. Enumerate all explorer.exe processes
  2. Kill each process with 5-second timeout
  3. Wait 1 second for cleanup
  4. Start new explorer.exe instance

Use Case: Necessary after certain registry changes to refresh shell integration, file associations, and icon cache.

Sources: OfficeScrubC2R-Native.cs:950-973

Shell Integration Workflow

flowchart TD
    Start["Cleanup Shortcuts"] --> CheckPinned{Shortcuts Exist?}
    
    CheckPinned -->|Yes| UnpinTaskbar["UnpinFromTaskbar()<br/>for each shortcut"]
    CheckPinned -->|No| End
    
    UnpinTaskbar --> UnpinStart["UnpinFromStartMenu()<br/>for each shortcut"]
    
    UnpinStart --> DeleteFiles["FileHelper.DeleteFile()<br/>Remove .lnk files"]
    
    DeleteFiles --> NeedRefresh{Shell Changes<br/>Require Refresh?}
    
    NeedRefresh -->|Yes| Restart["RestartExplorer()"]
    NeedRefresh -->|No| End
    
    Restart --> End["Shell Integration Cleaned"]
Loading

Sources: OfficeScrubC2R-Native.cs:864-974


TypeLibHelper

TypeLibHelper manages cleanup of COM type library registrations for Office components. Type libraries provide COM interface definitions and must be removed when their DLL files are deleted.

Class Structure

classDiagram
    class TypeLibHelper {
        -RegistryHelper _regHelper
        -static readonly string[] KnownTypeLibs
        +TypeLibHelper(RegistryHelper regHelper)
        +CleanupKnownTypeLibs() void
    }
    
    class RegistryHelper {
        +KeyExists(hive, subKey) bool
        +EnumerateKeys(hive, subKey) string[]
        +GetValue(hive, subKey, valueName) object
        +DeleteKey(hive, subKey) bool
    }
    
    TypeLibHelper --> RegistryHelper : uses
Loading

Sources: OfficeScrubC2R-Native.cs:1134-1209

Known Office Type Libraries

The class maintains a hardcoded list of 19 known Office type library GUIDs:

Type Library GUID Description
{000204EF-0000-0000-C000-000000000046} Microsoft Office Object Library
{00020813-0000-0000-C000-000000000046} Microsoft Excel Object Library
{00020905-0000-0000-C000-000000000046} Microsoft Word Object Library
{0002123C-0000-0000-C000-000000000046} Microsoft Outlook Object Library
{00024517-0000-0000-C000-000000000046} Microsoft Access Object Library
{0002E157-0000-0000-C000-000000000046} Microsoft OneNote Object Library
{00062FFF-0000-0000-C000-000000000046} Microsoft Outlook View Control
And 12 more... Various Office components

Sources: OfficeScrubC2R-Native.cs:1139-1151

CleanupKnownTypeLibs Method

Removes type library registrations for Office components whose DLL files no longer exist.

public void CleanupKnownTypeLibs()

Algorithm:

flowchart TD
    Start["For each known TypeLib GUID"] --> CheckExists{TypeLib Key<br/>Exists?}
    
    CheckExists -->|No| NextTL[Next TypeLib]
    CheckExists -->|Yes| EnumVer["Enumerate version keys"]
    
    EnumVer --> ForVer["For each version"]
    
    ForVer --> CheckPlat["Check platforms:<br/>0\Win32, 9\Win32,<br/>0\Win64, 9\Win64"]
    
    CheckPlat --> GetPath["Get DLL path<br/>from default value"]
    
    GetPath --> ExtractPath["Extract safe path<br/>(up to .dll extension)"]
    
    ExtractPath --> FileExists{DLL File<br/>Exists?}
    
    FileExists -->|Yes| CannotDelete["canDelete = false<br/>Break platform loop"]
    FileExists -->|No| NextPlat[Next platform]
    
    NextPlat --> MorePlat{More<br/>platforms?}
    MorePlat -->|Yes| CheckPlat
    MorePlat -->|No| CanDelete{canDelete<br/>== true?}
    
    CanDelete -->|Yes| DelVer["DeleteKey(version)"]
    CanDelete -->|No| NextVer[Next version]
    
    CannotDelete --> NextVer
    DelVer --> NextVer
    
    NextVer --> MoreVer{More<br/>versions?}
    MoreVer -->|Yes| ForVer
    MoreVer -->|No| CheckEmpty{All versions<br/>removed?}
    
    CheckEmpty -->|Yes| DelTL["DeleteKey(TypeLib)"]
    CheckEmpty -->|No| NextTL
    
    DelTL --> NextTL
    NextTL --> MoreTL{More<br/>TypeLibs?}
    MoreTL -->|Yes| Start
    MoreTL -->|No| Done[Cleanup Complete]
Loading

Platform Keys:

  • 0\Win32: Default 32-bit platform
  • 9\Win32: Neutral 32-bit platform
  • 0\Win64: Default 64-bit platform
  • 9\Win64: Neutral 64-bit platform

Path Safety: The method extracts a "safe path" by finding the last . character and including 4 characters after it (for .dll), preventing path parsing errors from embedded version strings.

Sources: OfficeScrubC2R-Native.cs:1158-1208

Type Library Registry Structure

graph TB
    subgraph "Registry: HKLM\Software\Classes\TypeLib"
        TL["{GUID}<br/>Type Library GUID"]
        TL --> V1["1.0<br/>Version"]
        TL --> V2["9.0<br/>Version"]
        
        V1 --> L1["0<br/>Locale ID"]
        V1 --> L2["9<br/>Locale ID"]
        
        L1 --> W32_1["Win32<br/>Platform"]
        L1 --> W64_1["Win64<br/>Platform"]
        
        W32_1 --> P1["Default Value:<br/>C:\...\MSOUTL.OLB"]
        W64_1 --> P2["Default Value:<br/>C:\...\MSOUTL.OLB"]
    end
    
    P1 -.Check Exists.-> F1[DLL File]
    P2 -.Check Exists.-> F2[DLL File]
    
    style F1 fill:#ffe6e6
    style F2 fill:#ffe6e6
Loading

Sources: OfficeScrubC2R-Native.cs:1134-1209


LicenseHelper

LicenseHelper handles Office licensing cleanup through the Software Protection Platform (SPP) and vNext license cache.

Class Structure

classDiagram
    class LicenseHelper {
        +CleanOSPP(int versionNT) void
        +ClearVNextLicenseCache(string localAppData) void
    }
    
    class ManagementScope {
        <<WMI>>
        +Connect() void
    }
    
    class ManagementObjectSearcher {
        <<WMI>>
        +Get() ManagementObjectCollection
    }
    
    class FileHelper {
        +DeleteDirectory(path, recursive, scheduleOnFail) bool
    }
    
    LicenseHelper ..> ManagementScope : creates
    LicenseHelper ..> ManagementObjectSearcher : uses
    LicenseHelper ..> FileHelper : uses
Loading

Sources: OfficeScrubC2R-Native.cs:1215-1273

CleanOSPP Method

Removes Office product keys from the Windows Software Protection Platform using WMI.

public void CleanOSPP(int versionNT)

Parameters:

  • versionNT: Windows NT version number (e.g., 601 = Windows 7, 602 = Windows 8)

WMI Classes by Windows Version:

Windows Version NT Version WMI Class
Windows 7 (6.1) 601 OfficeSoftwareProtectionProduct
Windows 8+ (6.2+) > 601 SoftwareLicensingProduct

Process:

sequenceDiagram
    participant LH as LicenseHelper
    participant WMI as WMI (root\cimv2)
    participant SPP as Software Protection Platform
    
    LH->>WMI: Connect()
    LH->>WMI: Query SoftwareLicensingProduct<br/>WHERE ApplicationId = Office GUID<br/>AND PartialProductKey <> NULL
    
    WMI-->>LH: Collection of licensed products
    
    loop For each product
        LH->>LH: Get ProductKeyID
        LH->>SPP: InvokeMethod("UninstallProductKey", keyID)
        SPP-->>LH: Success/Failure
    end
Loading

Office Application ID: 0ff1ce15-a989-479d-af46-f275c6370663 (constant identifier for Office products in SPP)

Sources: OfficeScrubC2R-Native.cs:1217-1253

ClearVNextLicenseCache Method

Deletes cached Office license files from local AppData directories.

public void ClearVNextLicenseCache(string localAppData)

Target Directories:

Path Description
%LOCALAPPDATA%\Microsoft\Office\Licenses Modern vNext license cache
%LOCALAPPDATA%\Microsoft\Office\15.0\Licensing Office 2013 licenses
%LOCALAPPDATA%\Microsoft\Office\16.0\Licensing Office 2016+ licenses

Process:

  1. Build array of license cache paths
  2. Check if each directory exists
  3. Use FileHelper.DeleteDirectory() with reboot scheduling
  4. Recursively remove all contents

Sources: OfficeScrubC2R-Native.cs:1255-1272

License Cleanup Workflow

flowchart TD
    Start["License Cleanup"] --> OSPP["CleanOSPP(versionNT)"]
    
    OSPP --> DetectWMI{Windows<br/>Version?}
    DetectWMI -->|<= 6.1| UseOSPP["Use OfficeSoftwareProtectionProduct"]
    DetectWMI -->|> 6.1| UseSLP["Use SoftwareLicensingProduct"]
    
    UseOSPP --> Query
    UseSLP --> Query["WMI Query:<br/>Office products with keys"]
    
    Query --> Products["For each licensed product"]
    Products --> Uninstall["UninstallProductKey()"]
    
    Uninstall --> Cache["ClearVNextLicenseCache(localAppData)"]
    
    Cache --> Del15["Delete Office\15.0\Licensing"]
    Cache --> Del16["Delete Office\16.0\Licensing"]
    Cache --> DelNew["Delete Office\Licenses"]
    
    Del15 --> Done
    Del16 --> Done
    DelNew --> Done["License Cleanup Complete"]
Loading

Sources: OfficeScrubC2R-Native.cs:1215-1273


ServiceHelper

ServiceHelper manages Windows service deletion for Office-related services (e.g., Click-to-Run service, update services).

Class Structure

classDiagram
    class ServiceHelper {
        +DeleteService(string serviceName) bool
    }
    
    class ManagementObjectSearcher {
        <<WMI>>
        +Get() ManagementObjectCollection
    }
    
    class ProcessStartInfo {
        +FileName string
        +Arguments string
        +UseShellExecute bool
    }
    
    ServiceHelper ..> ManagementObjectSearcher : uses
    ServiceHelper ..> ProcessStartInfo : fallback
Loading

Sources: OfficeScrubC2R-Native.cs:1279-1343

DeleteService Method

Deletes a Windows service using WMI with fallback to sc.exe command.

public bool DeleteService(string serviceName)

Two-Stage Approach:

flowchart TD
    Start["DeleteService(serviceName)"] --> WMI["Primary: WMI Approach"]
    
    WMI --> Query["WMI Query:<br/>Win32_Service<br/>WHERE Name LIKE 'serviceName%'"]
    
    Query --> Found{Services<br/>Found?}
    
    Found -->|Yes| CheckState{Service<br/>State?}
    
    CheckState -->|Running/Started| Stop["InvokeMethod('StopService')<br/>Wait 1 second"]
    CheckState -->|Stopped| Delete
    
    Stop --> Delete["InvokeMethod('Delete')"]
    
    Delete --> Success["Return true"]
    
    Found -->|No| Success
    
    WMI -->|Exception| Fallback["Fallback: sc.exe"]
    
    Fallback --> SCExec["Execute:<br/>sc.exe delete serviceName"]
    
    SCExec --> CheckExit{Exit Code<br/>== 0?}
    
    CheckExit -->|Yes| Success
    CheckExit -->|No| Fail["Return false"]
Loading

WMI Method:

  1. Connect to root\cimv2 namespace
  2. Query Win32_Service for matching service names (supports wildcards with LIKE)
  3. If service is running, invoke StopService method
  4. Wait 1 second for service to stop
  5. Invoke Delete method to remove service

Fallback Method: If WMI fails (permissions, WMI corruption, etc.):

  1. Execute sc.exe delete <serviceName>
  2. Wait up to 5 seconds for completion
  3. Return true if exit code is 0

Sources: OfficeScrubC2R-Native.cs:1281-1342

Common Office Services

Service Name Display Name Purpose
ClickToRunSvc Microsoft Office Click-to-Run Service C2R installation management
OfficeSvcManager Microsoft Office Service Manager Service coordination
officeupdate Microsoft Office Update Service Automatic updates

Service Deletion Process

sequenceDiagram
    participant Orch as Orchestrator
    participant SH as ServiceHelper
    participant WMI as WMI Service
    participant SCM as Service Control Manager
    
    Orch->>SH: DeleteService("ClickToRunSvc")
    
    SH->>WMI: Query Win32_Service
    WMI-->>SH: Service object
    
    SH->>SH: Check State
    
    alt Service is Running
        SH->>WMI: StopService()
        WMI->>SCM: Stop service
        SCM-->>WMI: Stopped
        WMI-->>SH: Success
        Note over SH: Wait 1 second
    end
    
    SH->>WMI: Delete()
    WMI->>SCM: Delete service
    SCM-->>WMI: Deleted
    WMI-->>SH: Success
    SH-->>Orch: true
    
    alt WMI Failure
        SH->>SCM: sc.exe delete ClickToRunSvc
        SCM-->>SH: Exit code 0
        SH-->>Orch: true
    end
Loading

Sources: OfficeScrubC2R-Native.cs:1279-1343


Helper Integration Patterns

Orchestrator Initialization

When OfficeScrubOrchestrator is instantiated, it creates instances of all helper classes:

sequenceDiagram
    participant Client as PowerShell
    participant Orch as OfficeScrubOrchestrator
    participant Helpers as Helper Classes
    
    Client->>Orch: new OfficeScrubOrchestrator(is64Bit)
    
    Orch->>Helpers: new RegistryHelper(is64Bit)
    Orch->>Helpers: new FileHelper()
    Orch->>Helpers: new ProcessHelper()
    Orch->>Helpers: new ShellHelper()
    Orch->>Helpers: new WindowsInstallerHelper(regHelper)
    Orch->>Helpers: new TypeLibHelper(regHelper)
    Orch->>Helpers: new LicenseHelper()
    Orch->>Helpers: new ServiceHelper()
    
    Orch-->>Client: Orchestrator instance<br/>(all helpers initialized)
Loading

Sources: OfficeScrubC2R-Native.cs:1360-1369

Helper Dependencies

graph TB
    subgraph "Independent Helpers"
        RH["RegistryHelper<br/>(requires is64Bit)"]
        FH["FileHelper"]
        PH["ProcessHelper"]
        SH["ShellHelper"]
        LH["LicenseHelper"]
        SVH["ServiceHelper"]
        GH["GuidHelper<br/>(static)"]
    end
    
    subgraph "Dependent Helpers"
        WIH["WindowsInstallerHelper"]
        TLH["TypeLibHelper"]
    end
    
    WIH --> RH
    WIH --> GH
    TLH --> RH
    LH --> FH
Loading

Dependency Rules:

  1. RegistryHelper requires architecture flag (is64Bit) for WOW64 support
  2. WindowsInstallerHelper requires RegistryHelper for registry access and uses GuidHelper for transformations
  3. TypeLibHelper requires RegistryHelper for type library enumeration
  4. LicenseHelper uses FileHelper for license cache deletion
  5. All other helpers are independent

Sources: OfficeScrubC2R-Native.cs:1349-1369

Typical Cleanup Sequence

sequenceDiagram
    participant PS as PowerShell
    participant Orch as Orchestrator
    participant LH as LicenseHelper
    participant PH as ProcessHelper
    participant SH as ShellHelper
    participant TLH as TypeLibHelper
    participant SVH as ServiceHelper
    participant FH as FileHelper
    
    PS->>Orch: Stage 1: Uninstall
    
    Orch->>LH: CleanOSPP(versionNT)
    LH-->>Orch: Licenses removed
    
    Orch->>LH: ClearVNextLicenseCache()
    LH-->>Orch: Cache cleared
    
    Orch->>PH: TerminateProcesses(OFFICE_PROCESSES)
    PH-->>Orch: PIDs terminated
    
    Orch->>SH: UnpinFromTaskbar(shortcuts)
    SH-->>Orch: Unpinned
    
    PS->>Orch: Stage 2: Registry Cleanup
    
    Orch->>TLH: CleanupKnownTypeLibs()
    TLH-->>Orch: TypeLibs cleaned
    
    PS->>Orch: Stage 3: File System Cleanup
    
    Orch->>SVH: DeleteService("ClickToRunSvc")
    SVH-->>Orch: Service deleted
    
    Orch->>FH: DeleteDirectory(officePath)
    FH-->>Orch: Files deleted
Loading

Sources: OfficeScrubC2R-Native.cs:1349-1405, docs/memory-bank/structure.md:60-79


Error Handling Patterns

All additional helper methods implement defensive error handling:

Try-Catch Pattern

flowchart TD
    Start["Helper Method"] --> Try["try block:<br/>Primary operation"]
    
    Try --> Success{Operation<br/>Succeeded?}
    Success -->|Yes| ReturnTrue["Return true/<br/>success value"]
    Success -->|No| Catch["catch block"]
    
    Catch --> Fallback{Fallback<br/>Available?}
    
    Fallback -->|Yes| TryFallback["Execute fallback<br/>(e.g., sc.exe)"]
    Fallback -->|No| ReturnFalse["Return false/<br/>void/empty"]
    
    TryFallback --> FallbackResult{Fallback<br/>Succeeded?}
    FallbackResult -->|Yes| ReturnTrue
    FallbackResult -->|No| ReturnFalse
Loading

Common Patterns:

  1. ShellHelper: Silent failure on COM exceptions (returns false)
  2. TypeLibHelper: Catches all exceptions during file checks, continues to next item
  3. LicenseHelper: Catches WMI exceptions, logs but continues
  4. ServiceHelper: Two-stage error handling (WMI → sc.exe)
  5. GuidHelper: Returns null on any parsing errors

Sources: OfficeScrubC2R-Native.cs:866-1343


Performance Considerations

GuidHelper Optimizations

The optimized version of GuidHelper (in reference implementation) includes several performance improvements:

Optimization Original Optimized Benefit
Decode table Allocated per call Static readonly field Eliminates allocations
String building StringBuilder Span<char> stackalloc Zero-heap allocations
Byte reversal Helper method Inline loop Reduced overhead

Sources: docs/OfficeScrubC2R-Native-Optimized-Real.cs:172-332

WMI Query Optimization

Both LicenseHelper and ServiceHelper use targeted WMI queries:

// Efficient: Select only needed properties
"SELECT ProductKeyID FROM SoftwareLicensingProduct WHERE ..."

// Instead of: SELECT * FROM ...

Benefits:

  • Reduced memory footprint
  • Faster query execution
  • Less network traffic in remote scenarios

Sources: OfficeScrubC2R-Native.cs:1226-1228, OfficeScrubC2R-Native.cs:1288

COM Object Disposal

ShellHelper properly releases COM objects through the dynamic runtime to prevent memory leaks during shell integration operations.

Sources: OfficeScrubC2R-Native.cs:864-974


Summary

The additional helper classes provide specialized functionality for Office cleanup:

Helper Primary Responsibility Key Methods
GuidHelper GUID format transformations GetExpandedGuid(), GetCompressedGuid(), GetDecodedGuid()
ShellHelper Shell integration cleanup UnpinFromTaskbar(), UnpinFromStartMenu(), RestartExplorer()
TypeLibHelper COM type library cleanup CleanupKnownTypeLibs()
LicenseHelper License removal CleanOSPP(), ClearVNextLicenseCache()
ServiceHelper Windows service deletion DeleteService()

These helpers work in conjunction with the core helpers (RegistryHelper, FileHelper, ProcessHelper, WindowsInstallerHelper) to provide comprehensive Office cleanup capabilities through the OfficeScrubOrchestrator.

Sources: OfficeScrubC2R-Native.cs:169-1405, docs/memory-bank/structure.md:60-79

Clone this wiki locally