Skip to main content
DotNET Build Buddy continuously monitors your workspace for changes to .NET source files and project files, automatically updating your project structure to stay in sync with your code.

How File Watching Works

The file watcher uses VS Code’s built-in file system watching capabilities to monitor changes:
// From fileWatcher.ts:20
export class FileWatcher implements vscode.Disposable {
    private watchers: vscode.FileSystemWatcher[] = [];
    private projectManager: DotNetProjectManager;
    private debounceTimer: NodeJS.Timeout | undefined;

    constructor(projectManager: DotNetProjectManager) {
        this.projectManager = projectManager;
        this.setupWatchers();
    }
}
File watching is automatically enabled when the extension activates. No manual setup required!

Watched Files

The file watcher monitors two categories of files:

1. Source Files

By default, watches all .NET source code files:
  • C# files - **/*.cs
  • F# files - **/*.fs
  • VB.NET files - **/*.vb

2. Project Files

Also monitors .NET project and solution files:
  • C# projects - **/*.csproj
  • F# projects - **/*.fsproj
  • VB.NET projects - **/*.vbproj
  • Solution files - **/*.sln
// From fileWatcher.ts:30
private setupWatchers(): void {
    const config = vscode.workspace.getConfiguration('dotnetBuildBuddy');
    const watchPatterns = config.get<string[]>('watchPatterns', 
        ['**/*.cs', '**/*.fs', '**/*.vb']);

    for (const pattern of watchPatterns) {
        const watcher = vscode.workspace.createFileSystemWatcher(pattern);
        
        watcher.onDidCreate(this.onFileChange.bind(this));
        watcher.onDidChange(this.onFileChange.bind(this));
        watcher.onDidDelete(this.onFileChange.bind(this));

        this.watchers.push(watcher);
    }

    const projectWatcher = vscode.workspace.createFileSystemWatcher(
        '**/*.{csproj,fsproj,vbproj,sln}');
    this.watchers.push(projectWatcher);
}

Monitored Events

The file watcher responds to three types of file system events:

File Created

New source files are automatically added to the appropriate project.

File Changed

Modified files trigger NuGet compatibility checks.

File Deleted

Removed files are automatically excluded from project files.

Excluded Directories

To avoid watching build artifacts and dependencies, certain directories are excluded by default:
// From fileWatcher.ts:81
private shouldIgnoreFile(filePath: string): boolean {
    const config = vscode.workspace.getConfiguration('dotnetBuildBuddy');
    const excludePatterns = config.get<string[]>('excludePatterns', 
        ['**/bin/**', '**/obj/**', '**/node_modules/**']);
    
    return excludePatterns.some(pattern => {
        const regex = new RegExp(pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*'));
        return regex.test(filePath);
    });
}
Default Excluded Patterns:
  • **/bin/** - Build output directories
  • **/obj/** - Intermediate compilation files
  • **/node_modules/** - Node.js dependencies (if present)
These exclusions prevent unnecessary updates from generated files and keep the watcher focused on your actual source code.

Debouncing

To prevent excessive updates when multiple files change rapidly, the file watcher uses debouncing:
// From fileWatcher.ts:91
private debounceUpdate(): void {
    if (this.debounceTimer) {
        clearTimeout(this.debounceTimer);
    }

    this.debounceTimer = setTimeout(async () => {
        console.log('DotNET Build Buddy: Triggering project file update...');
        try {
            await this.projectManager.updateAllProjectFiles();
            await this.projectManager.generateSolutionFile();
            console.log('DotNET Build Buddy: Project files and solution updated successfully');
        } catch (error) {
            console.error('DotNET Build Buddy: Error updating project files:', error);
            vscode.window.showErrorMessage(`DotNET Build Buddy: Failed to update project files: ${error}`);
        }
    }, 1000);
}

How Debouncing Works

1

Change Detected

A file is created, modified, or deleted in your workspace.
2

Timer Started

A 1-second timer begins. If another change occurs, the timer resets.
3

Updates Triggered

After 1 second of no changes, the update process begins.
4

Projects Updated

All project files and the solution file are updated in one batch.
The 1-second debounce delay is optimized for most workflows. This prevents Build Buddy from updating on every keystroke while keeping your project files responsive.

Automatic Update Flow

When a file change is detected, Build Buddy executes the following sequence:

Configuration Options

Enable/Disable Auto-Update

You can control whether automatic updates occur:
settings.json
{
  "dotnetBuildBuddy.autoUpdate": true
}
// From fileWatcher.ts:58
private onFileChange(uri: vscode.Uri): void {
    const config = vscode.workspace.getConfiguration('dotnetBuildBuddy');
    const autoUpdate = config.get<boolean>('autoUpdate', true);
    
    if (!autoUpdate) {
        console.log(`DotNET Build Buddy: Auto-update disabled, ignoring change to ${uri.fsPath}`);
        return;
    }
}
autoUpdate
boolean
default:"true"
Enable or disable automatic updates when files change. When disabled, you must use manual commands to update project files.

Customize Watch Patterns

settings.json
{
  "dotnetBuildBuddy.watchPatterns": [
    "**/*.cs",
    "**/*.fs",
    "**/*.vb"
  ]
}
watchPatterns
string[]
default:"['**/*.cs', '**/*.fs', '**/*.vb']"
Glob patterns for files to watch. Add or remove patterns based on your project needs.

Customize Exclusions

settings.json
{
  "dotnetBuildBuddy.excludePatterns": [
    "**/bin/**",
    "**/obj/**",
    "**/node_modules/**",
    "**/packages/**"
  ]
}
excludePatterns
string[]
Glob patterns for directories to exclude from watching. Files in these directories won’t trigger updates.

Logging and Debugging

The file watcher provides detailed console logging for debugging:
// Example log output
console.log(`DotNET Build Buddy: Setting up file watchers for patterns: **/*.cs, **/*.fs, **/*.vb`);
console.log(`DotNET Build Buddy: Excluding patterns: **/bin/**, **/obj/**, **/node_modules/**`);
console.log(`DotNET Build Buddy: Detected change in .NET source file: /path/to/file.cs`);
console.log(`DotNET Build Buddy: Triggering project file update...`);
console.log(`DotNET Build Buddy: Project files and solution updated successfully`);
To see detailed file watcher logs:
  1. Open the Developer Console: Help > Toggle Developer Tools
  2. Switch to the Console tab
  3. Filter for “DotNET Build Buddy” messages
  4. Monitor real-time file change events and update operations

Performance Considerations

Large Workspaces

For workspaces with thousands of files:
Optimized: VS Code’s file watchers are highly efficient and use native OS file system events
Debouncing: The 1-second delay prevents excessive updates during bulk operations
Selective watching: Only monitors .NET-related files, not every file in your workspace

Resource Usage

// From fileWatcher.ts:110
public dispose(): void {
    if (this.debounceTimer) {
        clearTimeout(this.debounceTimer);
    }

    for (const watcher of this.watchers) {
        watcher.dispose();
    }
    this.watchers = [];
}
File watchers are properly disposed when:
  • The extension is deactivated
  • VS Code is closed
  • The workspace is changed

Common Scenarios

Scenario 1: Adding New Files

1

Create new file

You create Services/UserService.cs in your workspace
2

Watcher detects

File watcher detects the new .cs file
3

Debounce waits

Timer starts (1 second)
4

Project updates

Services.csproj is updated to include the new file
5

Solution updates

If needed, the solution file is regenerated

Scenario 2: Bulk File Operations

1

Multiple changes

You paste 10 files from another project
2

Timer resets

Each file change resets the 1-second timer
3

Single update

Only one update occurs after all files are added
4

Efficient processing

All 10 files are processed in a single batch

Scenario 3: Git Branch Switch

1

Branch switch

You switch to a different Git branch with different files
2

Multiple events

VS Code reports many file additions/deletions
3

Debounce handles it

Single update after all changes complete
4

Projects sync

Project files reflect the new branch state

Integration with Other Features

The file watcher triggers multiple Build Buddy features:

NuGet Compatibility Checks

Every automatic update includes compatibility verification:
// From fileWatcher.ts:96
await this.projectManager.updateAllProjectFiles();
// This internally calls:
// - checkAllProjectCompatibility()
// - updateDiagnostics()
// - reportCompatibilityIssues()

Solution Regeneration

// From fileWatcher.ts:101
await this.projectManager.generateSolutionFile();
// Ensures the solution file includes all projects

Manual Override

Even with auto-update disabled, you can trigger updates manually:
Ctrl+Shift+P (Windows/Linux)
Cmd+Shift+P (Mac)

DotNET Build Buddy: Update Project Files

Troubleshooting

Symptoms: Changes to source files don’t trigger updatesSolutions:
  • Check that autoUpdate is enabled in settings
  • Verify files aren’t in excluded directories (bin/, obj/)
  • Check watch patterns match your file extensions
  • Look for errors in the Developer Console
Symptoms: Projects update too frequently, causing performance issuesSolutions:
  • The debounce timer should prevent this, but if you experience it:
  • Disable auto-update and use manual commands
  • Check if other extensions are modifying files
  • Add problematic directories to excludePatterns
Symptoms: File changes detected but projects don’t updateSolutions:
  • Check Developer Console for error messages
  • Verify write permissions on project files
  • Try manual update command to see specific errors
  • Ensure project files aren’t locked by another process
Symptoms: Files in bin/ or obj/ cause updatesSolutions:
  • Verify excludePatterns syntax in settings
  • Ensure patterns use glob format (**/bin/**)
  • Check that patterns cover your actual directory structure
  • Use absolute paths for debugging in console logs

Best Practices

Keep auto-update enabled

Auto-update provides the best developer experience, keeping your project files always in sync.

Trust the debouncing

The 1-second delay is optimized. Don’t worry about rapid file changes.

Exclude build artifacts

Always exclude bin/, obj/, and package directories for best performance.

Check the console

When debugging issues, the Developer Console shows exactly what the watcher is doing.

Build docs developers (and LLMs) love