Skip to content

Developer Guide

Calvindd2f edited this page Jan 14, 2026 · 1 revision

Developer Guide

Relevant source files

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

This guide provides comprehensive information for developers contributing to OfficeScrubC2R. It covers the development environment setup, build process, code organization, testing procedures, and release workflow. For information about using OfficeScrubC2R as an end user, see User Guide. For architectural details about how the system works internally, see Architecture.

Scope

This guide is intended for:

  • Contributors adding features or fixing bugs
  • Maintainers managing releases and CI/CD
  • Developers creating forks or derivative works
  • Technical reviewers understanding the codebase

Prerequisites

Before beginning development, you must have:

Requirement Version Purpose
Windows 10/11 or Server 2016+ Development and testing platform
PowerShell 5.1 or 7+ Module development and testing
.NET Framework 4.5+ Native library compilation (csc.exe)
.NET SDK 7.0+ (optional) Cross-platform compilation
Git Latest Version control
Administrator Rights Required Testing cleanup operations

Optional but Recommended:

  • PSScriptAnalyzer module for code analysis
  • Pester module for testing
  • Windows Sandbox or Hyper-V for safe testing

Sources: docs/memory-bank/product.md:59-64, CONTRIBUTING.md:44-56

Quick Start for Developers

# Clone the repository
git clone https://github.com/Calvindd2f/OfficeScrubC2R.git
cd OfficeScrubC2R

# Install development dependencies
Install-Module -Name PSScriptAnalyzer -Scope CurrentUser
Install-Module -Name Pester -Scope CurrentUser

# Build the native library
.\build.ps1

# Import the module for testing
Import-Module .\OfficeScrubC2R.psd1 -Force

# Run code analysis
Invoke-ScriptAnalyzer -Path . -Recurse

# Test detection (safe, no modifications)
Invoke-OfficeScrubC2R -DetectOnly -Verbose

Sources: CONTRIBUTING.md:44-69

Development Environment Architecture

graph TB
    subgraph "Development Machine"
        Editor["Code Editor<br/>VS Code / ISE"]
        Git["Git Client<br/>Version Control"]
        PS["PowerShell<br/>5.1 or 7+"]
    end
    
    subgraph "Source Files"
        PSM["OfficeScrubC2R.psm1<br/>Main Module"]
        UTIL["OfficeScrubC2R-Utilities.psm1<br/>Utilities"]
        CS["OfficeScrubC2R-Native.cs<br/>C# Source"]
        PSD["OfficeScrubC2R.psd1<br/>Manifest"]
    end
    
    subgraph "Build Tools"
        BuildScript["build.ps1<br/>Build Orchestrator"]
        CSC["csc.exe<br/>.NET Framework Compiler"]
        DotNet["dotnet build<br/>.NET Core Compiler"]
    end
    
    subgraph "Build Artifacts"
        DLL["OfficeScrubNative.dll<br/>.NET Framework 4.5"]
        CoreDLL["OfficeScrubNative.Core.dll<br/>.NET Core 7+"]
    end
    
    subgraph "Verification Tools"
        PSA["PSScriptAnalyzer<br/>Code Analysis"]
        Pester["Pester<br/>Unit Tests"]
        Verify["Verify-NativeBuild.ps1<br/>Build Verification"]
        Validate["Validate-Module.ps1<br/>Module Validation"]
    end
    
    subgraph "Testing Environment"
        Sandbox["Windows Sandbox<br/>Safe Testing"]
        VM["Virtual Machine<br/>Full Testing"]
    end
    
    Editor --> PSM
    Editor --> UTIL
    Editor --> CS
    Editor --> PSD
    
    BuildScript --> CSC
    BuildScript --> DotNet
    CS --> CSC
    CS --> DotNet
    CSC --> DLL
    DotNet --> CoreDLL
    
    PSM --> PSA
    UTIL --> PSA
    DLL --> Verify
    CoreDLL --> Verify
    PSD --> Validate
    
    DLL --> PS
    PSM --> PS
    PS --> Sandbox
    PS --> VM
    
    Git --> PSM
    Git --> CS
Loading

Diagram: Development Environment Setup

This diagram shows the complete development environment. Developers work with four main source files (OfficeScrubC2R.psm1, OfficeScrubC2R-Utilities.psm1, OfficeScrubC2R-Native.cs, OfficeScrubC2R.psd1) using their preferred editor. The build.ps1 script orchestrates compilation using either csc.exe for .NET Framework or dotnet build for .NET Core. Verification tools (PSScriptAnalyzer, Pester, Verify-NativeBuild.ps1, Validate-Module.ps1) ensure code quality and correctness. Testing occurs in isolated environments (Windows Sandbox or VMs) to prevent damage to the development machine.

Sources: docs/memory-bank/structure.md:1-59, CONTRIBUTING.md:44-56

Development Workflow

flowchart TD
    Start["Start Development"] --> Fork["Fork Repository"]
    Fork --> Clone["git clone<br/>Local Copy"]
    Clone --> Branch["git checkout -b<br/>feature/branch-name"]
    
    Branch --> Code["Edit Source Files"]
    Code --> Build[".\build.ps1<br/>Compile Native DLL"]
    
    Build --> BuildOK{Build<br/>Success?}
    BuildOK -->|No| FixBuild["Fix Build Errors"]
    FixBuild --> Build
    BuildOK -->|Yes| Analyze["Invoke-ScriptAnalyzer<br/>Code Quality Check"]
    
    Analyze --> AnalyzeOK{PSScriptAnalyzer<br/>Pass?}
    AnalyzeOK -->|No| FixAnalyze["Fix Analysis Issues"]
    AnalyzeOK -->|Yes| Test["Manual Testing<br/>Import & Run"]
    FixAnalyze --> Analyze
    
    Test --> TestOK{Tests<br/>Pass?}
    TestOK -->|No| FixTest["Fix Test Failures"]
    FixTest --> Code
    TestOK -->|Yes| Commit["git commit -m<br/>'Clear Message'"]
    
    Commit --> Push["git push origin<br/>feature/branch-name"]
    Push --> PR["Create Pull Request<br/>on GitHub"]
    
    PR --> CI["GitHub Actions<br/>CI Pipeline Runs"]
    CI --> CIOK{CI<br/>Pass?}
    CIOK -->|No| FixCI["Fix CI Failures"]
    FixCI --> Code
    CIOK -->|Yes| Review["Code Review<br/>by Maintainers"]
    
    Review --> ReviewOK{Review<br/>Approved?}
    ReviewOK -->|Changes Needed| Address["Address Feedback"]
    Address --> Code
    ReviewOK -->|Approved| Merge["Merge to Main"]
    
    Merge --> Release["Release Process<br/>if applicable"]
Loading

Diagram: Development and Contribution Workflow

This flowchart illustrates the complete development cycle. Developers fork the repository, create feature branches, make code changes, and build using build.ps1. Code quality is verified with Invoke-ScriptAnalyzer, followed by manual testing. Changes are committed with clear messages and pushed to the fork. Pull requests trigger the GitHub Actions CI pipeline (.github/workflows/ci.yml), which must pass before code review. After maintainer approval, changes merge to the main branch and may be included in releases.

Sources: CONTRIBUTING.md:34-43, docs/memory-bank/structure.md:37-46

Repository Structure Map

graph TB
    subgraph "Root Files"
        PSD1["OfficeScrubC2R.psd1<br/>Module Manifest<br/>Version, Dependencies, Exports"]
        PSM1["OfficeScrubC2R.psm1<br/>Main Module<br/>Entry Points, Orchestration"]
        UTIL["OfficeScrubC2R-Utilities.psm1<br/>Nested Module<br/>Helper Functions"]
        CS["OfficeScrubC2R-Native.cs<br/>C# Source<br/>4000+ lines"]
        DLL["OfficeScrubNative.dll<br/>Pre-compiled Binary<br/>Performance Layer"]
        BUILD["build.ps1<br/>Build Script<br/>Compilation Logic"]
    end
    
    subgraph "Configuration"
        PSAA["PSScriptAnalyzerSettings.psd1<br/>Linter Rules"]
        GIT[".gitignore<br/>.gitattributes<br/>Git Config"]
    end
    
    subgraph "docs/"
        BUILD_MD["BUILD.md<br/>Build Instructions"]
        CHANGELOG["CHANGELOG.md<br/>Version History"]
        CONTRIB["CONTRIBUTING.md<br/>Contributor Guide"]
        CHECKLIST["CHECKLIST.md<br/>Development Checklist"]
        SOURCE["source/<br/>Original VBScript<br/>Reference Implementation"]
    end
    
    subgraph ".github/"
        CI["workflows/ci.yml<br/>GitHub Actions<br/>Test & Validate Jobs"]
        SCRIPTS["scripts/<br/>utils.ps1<br/>Validate-Module.ps1"]
    end
    
    subgraph "tests/"
        TEST["Test-OfficeScrubC2R.ps1<br/>Module Test Suite"]
        VERIFY["Verify-NativeBuild.ps1<br/>Build Verification"]
    end
    
    subgraph "Native Library Classes"
        ORCH["OfficeScrubOrchestrator<br/>Central Coordinator"]
        REG["RegistryHelper<br/>Registry Operations"]
        FILE["FileHelper<br/>File Operations"]
        PROC["ProcessHelper<br/>Process Management"]
        MSI["WindowsInstallerHelper<br/>MSI Cleanup"]
        OTHER["TypeLibHelper<br/>LicenseHelper<br/>ServiceHelper<br/>ShellHelper<br/>GuidHelper"]
    end
    
    PSM1 -.imports.-> UTIL
    PSM1 -.loads.-> DLL
    BUILD -.compiles.-> CS
    CS -.produces.-> DLL
    CS -.contains.-> ORCH
    CS -.contains.-> REG
    CS -.contains.-> FILE
    CS -.contains.-> PROC
    CS -.contains.-> MSI
    CS -.contains.-> OTHER
    CI -.runs.-> BUILD
    CI -.runs.-> TEST
    CI -.validates.-> PSD1
Loading

Diagram: Repository Structure and Component Relationships

This diagram maps the physical file structure to logical components. The root contains the four primary source files (OfficeScrubC2R.psd1, OfficeScrubC2R.psm1, OfficeScrubC2R-Utilities.psm1, OfficeScrubC2R-Native.cs) along with the pre-compiled OfficeScrubNative.dll and build.ps1 script. The docs/ directory holds documentation, .github/ contains CI/CD configuration, and tests/ has validation scripts. The OfficeScrubC2R-Native.cs file contains nine major classes (shown bottom right): OfficeScrubOrchestrator coordinates eight specialized helpers for different Windows subsystems.

Sources: docs/memory-bank/structure.md:1-59, docs/memory-bank/structure.md:61-79

Key Development Concepts

Hybrid Architecture Understanding

The codebase uses a two-layer hybrid architecture:

Layer Technology Files Purpose
Orchestration Layer PowerShell OfficeScrubC2R.psm1
OfficeScrubC2R-Utilities.psm1
User interface, workflow control, parameter handling
Performance Layer C# OfficeScrubC2R-Native.cs
OfficeScrubNative.dll
High-speed registry/file operations, Win32 APIs

Why This Matters for Developers:

  • PowerShell changes affect user interface, parameter validation, logging, workflow
  • C# changes affect performance-critical operations, Win32 API calls, parallel processing
  • Changes to helper classes in C# require recompilation with build.ps1
  • Changes to PowerShell only require module reload (Import-Module -Force)

Sources: docs/memory-bank/structure.md:80-99, docs/memory-bank/product.md:26-32

Build System Architecture

flowchart LR
    subgraph "Input"
        Source["OfficeScrubC2R-Native.cs<br/>4000+ lines C#"]
    end
    
    subgraph "build.ps1 Logic"
        Check{".NET<br/>Framework<br/>Available?"}
        Framework["csc.exe<br/>/target:library<br/>/optimize+"]
        Core["dotnet build<br/>--configuration Release"]
    end
    
    subgraph "Outputs"
        FW["OfficeScrubNative.dll<br/>.NET Framework 4.5+<br/>Windows PowerShell"]
        NC["OfficeScrubNative.Core.dll<br/>.NET Core 7+<br/>PowerShell 7+"]
    end
    
    subgraph "Verification"
        Load["Test Assembly Load<br/>both PS editions"]
        Export["Verify Type Export<br/>Classes Available"]
    end
    
    Source --> Check
    Check -->|Yes| Framework
    Check -->|No| Core
    Framework --> FW
    Core --> NC
    FW --> Load
    NC --> Load
    Load --> Export
Loading

Diagram: Build System Flow

The build.ps1 script detects available .NET tools and compiles OfficeScrubC2R-Native.cs using the appropriate compiler. When .NET Framework is available, it uses csc.exe with optimization flags to produce OfficeScrubNative.dll for Windows PowerShell 5.1. Optionally, it uses dotnet build to create OfficeScrubNative.Core.dll for PowerShell 7+. Verification steps ensure both assemblies load correctly and export expected types (OfficeScrubOrchestrator, helper classes).

Sources: docs/memory-bank/structure.md:117-124, CONTRIBUTING.md:58-68

Native Library Class Hierarchy

The OfficeScrubC2R-Native.cs file defines the following class structure:

OfficeScrubOrchestrator (main coordinator)
├── RegistryHelper (constructor parameter)
│   ├── KeyExists()
│   ├── DeleteKey()
│   ├── DeleteValue()
│   ├── EnumerateKeys()
│   ├── GetValue()
│   └── SetValue()
├── FileHelper (constructor parameter)
│   ├── DeleteFile()
│   ├── DeleteDirectory()
│   └── PendingDeletes (property)
├── ProcessHelper (constructor parameter)
│   ├── TerminateProcesses()
│   ├── GetProcessesUsingPath()
│   └── IsProcessRunning()
├── WindowsInstallerHelper (constructor parameter)
│   ├── CleanupUpgradeCodes()
│   ├── CleanupProducts()
│   ├── CleanupComponents()
│   └── CleanupPublishedComponents()
├── TypeLibHelper (constructor parameter)
│   └── CleanupTypeLibraries()
├── LicenseHelper (constructor parameter)
│   ├── RemoveLicenses()
│   └── ClearvNextCache()
├── ServiceHelper (constructor parameter)
│   ├── DeleteService()
│   └── ServiceExists()
└── ShellHelper (constructor parameter)
    ├── UnpinFromTaskbar()
    └── UnpinFromStartMenu()

GuidHelper (static utility class)
├── GetExpandedGuid()
├── GetCompressedGuid()
└── GetDecodedGuid()

OfficeConstants (static constants class)
├── OFFICE_ID
├── PROD_LEN
├── CULTURE_LEN
└── Registry paths, process names, etc.

Design Principle: Each helper class is dependency-injected into OfficeScrubOrchestrator constructor. This enables testing with mock helpers and maintains separation of concerns.

Sources: docs/memory-bank/structure.md:61-79, docs/memory-bank/guidelines.md:44-56

Coding Standards Quick Reference

PowerShell Conventions

# Function naming: Verb-Noun with approved verbs
function Get-OfficeScrubHelpers {
    [CmdletBinding()]  # Always use for advanced functions
    param(
        [Parameter(Mandatory)]  # Explicit attributes
        [string]$Path,          # Explicit types
        
        [switch]$Force          # Use [switch] for boolean flags
    )
    
    # Comment-based help required for exported functions
    <#
    .SYNOPSIS
    Brief description
    
    .PARAMETER Path
    Parameter description
    #>
}

Key Rules:

  • PascalCase for function names
  • Use approved verbs (Get-Verb to check)
  • Always specify parameter types
  • Add [CmdletBinding()] for advanced functions
  • Include comment-based help

Sources: CONTRIBUTING.md:71-96, docs/memory-bank/guidelines.md:5-12

C# Conventions

// Class naming: PascalCase
public class RegistryHelper
{
    // Private fields: _camelCase
    private readonly bool _is64Bit;
    private readonly HashSet<string> _processedKeys;
    
    // Properties: PascalCase
    public RegistryKey Registry { get; }
    
    // Methods: PascalCase
    public bool DeleteKey(string keyPath)
    {
        // Silent failure pattern: try-catch returning bool
        try
        {
            // Implementation
            return true;
        }
        catch
        {
            return false;
        }
    }
    
    // Constants: UPPER_CASE
    private const int KEY_WOW64_64KEY = 0x0100;
}

Key Rules:

  • PascalCase for classes, methods, properties
  • _camelCase for private fields
  • UPPER_CASE for constants
  • Silent failure pattern for operation methods
  • Always dispose resources in finally blocks

Sources: docs/memory-bank/guidelines.md:5-12, docs/memory-bank/guidelines.md:26-42, CONTRIBUTING.md:98-121

Critical Patterns to Follow

Pattern Implementation Example Location
WOW64 Support Check both 64-bit and 32-bit registry views OfficeScrubC2R-Native.cs - RegistryHelper
Parallel Processing Use Task.Run() with Task.WaitAll() OfficeScrubC2R-Native.cs - ProcessHelper.TerminateProcesses()
Helper Injection Constructor dependency injection OfficeScrubC2R-Native.cs - OfficeScrubOrchestrator
P/Invoke Internal static NativeMethods class OfficeScrubC2R-Native.cs - NativeMethods
Silent Failure Return bool/null, don't throw All helper methods
Resource Disposal using statements or finally blocks OfficeScrubC2R-Native.cs - ProcessHelper

Sources: docs/memory-bank/guidelines.md:44-68, docs/memory-bank/guidelines.md:69-118

Testing Strategy

graph TB
    subgraph "Static Analysis"
        PSA["PSScriptAnalyzer<br/>Invoke-ScriptAnalyzer"]
        Rules["PSScriptAnalyzerSettings.psd1<br/>Rule Configuration"]
    end
    
    subgraph "Build Verification"
        BuildTest["Verify-NativeBuild.ps1<br/>Assembly Load Test"]
        TypeCheck["Type Export Verification<br/>Class Availability"]
    end
    
    subgraph "Module Validation"
        Validate["Validate-Module.ps1<br/>Gallery Compatibility"]
        Manifest["Test-ModuleManifest<br/>Manifest Validation"]
        Files["File List Check<br/>Required Files Present"]
    end
    
    subgraph "Functional Testing"
        Import["Import-Module Test<br/>Module Loads"]
        Detect["Detection-Only Test<br/>Safe Execution"]
        Manual["Manual Full Test<br/>VM/Sandbox Only"]
    end
    
    subgraph "CI/CD Testing"
        GHA["GitHub Actions<br/>.github/workflows/ci.yml"]
        TestJob["Test Job<br/>Build + Import + Analyze"]
        ValidateJob["Validate Job<br/>Gallery Readiness"]
    end
    
    Code["Code Changes"] --> PSA
    Code --> BuildTest
    PSA --> Rules
    
    BuildTest --> TypeCheck
    TypeCheck --> Import
    
    Validate --> Manifest
    Validate --> Files
    
    Import --> Detect
    Detect --> Manual
    
    Code --> GHA
    GHA --> TestJob
    GHA --> ValidateJob
    TestJob --> PSA
    TestJob --> BuildTest
    ValidateJob --> Validate
Loading

Diagram: Multi-Layer Testing Strategy

Testing occurs at multiple levels. Static Analysis uses PSScriptAnalyzer with custom rules from PSScriptAnalyzerSettings.psd1. Build Verification (Verify-NativeBuild.ps1) ensures the compiled DLL loads in both PowerShell editions and exports expected types. Module Validation (Validate-Module.ps1) checks PowerShell Gallery compatibility, manifest correctness, and required file presence. Functional Testing progresses from safe module import through detection-only mode to full cleanup (VM/Sandbox only). CI/CD Testing runs automatically via GitHub Actions (.github/workflows/ci.yml) with parallel Test and Validate jobs.

Sources: CONTRIBUTING.md:123-155, docs/memory-bank/structure.md:37-46

Test Execution Checklist

Use this checklist before submitting a pull request:

# 1. Static Analysis
Invoke-ScriptAnalyzer -Path . -Recurse -Settings PSScriptAnalyzerSettings.psd1

# 2. Build Verification
.\build.ps1
.\tests\Verify-NativeBuild.ps1

# 3. Module Import (both editions)
# Windows PowerShell 5.1
powershell.exe -Command "Import-Module .\OfficeScrubC2R.psd1 -Force; Get-Command -Module OfficeScrubC2R"

# PowerShell 7+
pwsh -Command "Import-Module .\OfficeScrubC2R.psd1 -Force; Get-Command -Module OfficeScrubC2R"

# 4. Manifest Validation
Test-ModuleManifest .\OfficeScrubC2R.psd1

# 5. Detection-Only Test (Safe)
Import-Module .\OfficeScrubC2R.psd1 -Force
Invoke-OfficeScrubC2R -DetectOnly -Verbose

# 6. Full Test (VM/Sandbox Only - DESTRUCTIVE)
# DO NOT RUN ON DEVELOPMENT MACHINE
Invoke-OfficeScrubC2R -Force -Verbose

Sources: CONTRIBUTING.md:123-155

Common Development Tasks

Adding a New Helper Method

When adding functionality to an existing helper class:

  1. Locate the helper class in OfficeScrubC2R-Native.cs
  2. Add method following naming conventions (PascalCase, action-oriented)
  3. Implement silent failure pattern (try-catch returning bool/null)
  4. Handle resources with using or finally blocks
  5. Add XML documentation comments
  6. Rebuild with .\build.ps1
  7. Test assembly load with .\tests\Verify-NativeBuild.ps1
  8. Update documentation if user-facing

Example adding a method to FileHelper:

/// <summary>
/// Checks if a file is locked by another process
/// </summary>
/// <param name="filePath">Full path to file</param>
/// <returns>True if file is locked, false otherwise</returns>
public bool IsFileLocked(string filePath)
{
    try
    {
        using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
        {
            return false; // Successfully opened, not locked
        }
    }
    catch
    {
        return true; // Failed to open, likely locked
    }
}

Sources: docs/memory-bank/guidelines.md:26-42, CONTRIBUTING.md:98-121

Modifying PowerShell Functions

When modifying PowerShell module functions:

  1. Locate function in OfficeScrubC2R.psm1 or OfficeScrubC2R-Utilities.psm1
  2. Update implementation following PowerShell best practices
  3. Update comment-based help if signature or behavior changes
  4. Test with PSScriptAnalyzer: Invoke-ScriptAnalyzer -Path .\OfficeScrubC2R.psm1
  5. Reload module: Import-Module .\OfficeScrubC2R.psd1 -Force
  6. Test manually with -Verbose and -WhatIf where applicable
  7. Update manifest (OfficeScrubC2R.psd1) if adding/removing exports

Sources: CONTRIBUTING.md:71-96, docs/memory-bank/structure.md:61-65

Adding a New Helper Class

To add an entirely new helper class to the native library:

  1. Add class definition in OfficeScrubC2R-Native.cs following existing patterns
  2. Create constructor accepting required dependencies
  3. Implement methods with silent failure pattern
  4. Add to OfficeScrubOrchestrator:
    • Add private field: private readonly NewHelper _newHelper;
    • Add constructor parameter
    • Assign in constructor body
    • Expose as property: public NewHelper NewHelper => _newHelper;
  5. Rebuild: .\build.ps1
  6. Expose in PowerShell via Get-OfficeScrubHelpers function
  7. Add tests and documentation

Sources: docs/memory-bank/guidelines.md:44-56, docs/memory-bank/structure.md:61-79

CI/CD Pipeline Details

The .github/workflows/ci.yml file defines two parallel jobs:

Test Job

- name: Test
  runs-on: windows-latest
  steps:
    - Checkout code
    - Build native DLL (build.ps1)
    - Import module
    - Run PSScriptAnalyzer
    - Verify build (Verify-NativeBuild.ps1)

Purpose: Ensures code compiles, imports cleanly, passes static analysis, and builds successfully on both PowerShell editions.

Validate Job

- name: Validate
  runs-on: windows-latest
  steps:
    - Checkout code
    - Validate module manifest
    - Check required files present
    - Verify PowerShell Gallery compatibility
    - Check zone identifiers (unblocked files)

Purpose: Ensures module meets PowerShell Gallery requirements and can be published.

Note: CI/CD runs automatically on push and pull requests. Both jobs must pass before merging.

Sources: docs/memory-bank/structure.md:37-46

Release Process Overview

The release workflow follows semantic versioning (MAJOR.MINOR.PATCH):

  1. Update Version

    • Edit ModuleVersion in OfficeScrubC2R.psd1
    • Follow semantic versioning rules
  2. Update CHANGELOG.md

    • Add new version section
    • Document changes under Added/Changed/Fixed/Removed
  3. Build and Test

    .\build.ps1
    Test-ModuleManifest .\OfficeScrubC2R.psd1
    Invoke-ScriptAnalyzer -Path . -Recurse
  4. Create Git Tag

    git tag -a v2.19.3 -m "Release v2.19.3"
    git push --tags
  5. Create GitHub Release

    • Navigate to repository → Releases → Draft new release
    • Select tag, add release notes
    • Attach compiled DLL if applicable
  6. Publish to PowerShell Gallery (Maintainers only)

    Publish-Module -Path . -NuGetApiKey $apiKey -Verbose

Important: Versions published to PowerShell Gallery cannot be deleted or overwritten. Ensure thorough testing before publishing.

Sources: CONTRIBUTING.md:184-211, CHANGELOG.md:1-18

Troubleshooting Development Issues

Build Failures

Issue Cause Solution
"csc.exe not found" .NET Framework not installed Install .NET Framework 4.5+ or use dotnet build
"error CS0234: Type or namespace" Missing assembly reference Check build.ps1 references: System.Management.dll, Microsoft.CSharp.dll
"Assembly load failed" DLL blocked by Windows Unblock: Unblock-File .\OfficeScrubNative.dll

Module Import Failures

Issue Cause Solution
"File not found" DLL not compiled Run .\build.ps1 first
"Cannot load type" DLL compilation failed Check build output for errors
"Assembly version mismatch" Mixed PS editions Clean rebuild: Remove-Item .\*.dll; .\build.ps1

PSScriptAnalyzer Errors

Common issues:

  • PSAvoidUsingCmdletAliases: Use full cmdlet names (Where-Object not where)
  • PSUseSingularNouns: Function names should use singular nouns
  • PSAvoidUsingWriteHost: Use Write-Output, Write-Verbose, or Write-Information

Fix all issues before submitting pull requests. Check with:

Invoke-ScriptAnalyzer -Path . -Recurse -Settings PSScriptAnalyzerSettings.psd1

Sources: CONTRIBUTING.md:123-155

Additional Resources

For deeper information on specific topics covered in this guide:

Sources: CONTRIBUTING.md:1-232, docs/memory-bank/product.md:1-72, docs/memory-bank/guidelines.md:1-179, docs/memory-bank/structure.md:1-132

Clone this wiki locally