event_tracing_windows 0.0.1 copy "event_tracing_windows: ^0.0.1" to clipboard
event_tracing_windows: ^0.0.1 copied to clipboard

PlatformWindows

A Flutter plugin for Windows that uses ETW (Event Tracing for Windows) to monitor process and file system activities in real-time.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/services.dart';
import 'package:event_tracing_windows/event_tracing_windows.dart';
import 'package:intl/intl.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Windows ETW 监控',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _plugin = EventTracingWindows();

  bool _isProcessMonitoringActive = false;
  bool _isFileMonitoringActive = false;

  final List<ProcessEvent> _processEvents = [];
  final List<FileEvent> _fileEvents = [];

  StreamSubscription<ProcessEvent>? _processSubscription;
  StreamSubscription<FileEvent>? _fileSubscription;

  final int _maxEvents = 100; // 最多保留的事件数量

  Future<void> _toggleProcessMonitoring() async {
    if (_isProcessMonitoringActive) {
      // 停止监听
      await _plugin.stopProcessMonitoring();
      await _processSubscription?.cancel();
      _processSubscription = null;

      setState(() {
        _isProcessMonitoringActive = false;
      });
    } else {
      // 开始监听
      final success = await _plugin.startProcessMonitoring();

      if (success) {
        _processSubscription = _plugin.processEventStream.listen((event) {
          setState(() {
            _processEvents.insert(0, event);
            if (_processEvents.length > _maxEvents) {
              _processEvents.removeLast();
            }
          });
        });

        setState(() {
          _isProcessMonitoringActive = true;
        });

        if (!mounted) return;
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('进程监控已启动')));
      } else {
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('启动进程监控失败,请确保以管理员权限运行'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  Future<void> _toggleFileMonitoring() async {
    if (_isFileMonitoringActive) {
      // 停止监听
      await _plugin.stopFileMonitoring();
      await _fileSubscription?.cancel();
      _fileSubscription = null;

      setState(() {
        _isFileMonitoringActive = false;
      });
    } else {
      // 开始监听
      final success = await _plugin.startFileMonitoring();

      if (success) {
        _fileSubscription = _plugin.fileEventStream.listen((event) {
          setState(() {
            _fileEvents.insert(0, event);
            if (_fileEvents.length > _maxEvents) {
              _fileEvents.removeLast();
            }
          });
        });

        setState(() {
          _isFileMonitoringActive = true;
        });

        if (!mounted) return;
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(const SnackBar(content: Text('文件监控已启动')));
      } else {
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('启动文件监控失败,请确保以管理员权限运行'),
            backgroundColor: Colors.red,
          ),
        );
      }
    }
  }

  void _clearProcessEvents() {
    setState(() {
      _processEvents.clear();
    });
  }

  void _clearFileEvents() {
    setState(() {
      _fileEvents.clear();
    });
  }

  @override
  void dispose() {
    _processSubscription?.cancel();
    _fileSubscription?.cancel();
    _plugin.stopProcessMonitoring();
    _plugin.stopFileMonitoring();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Windows ETW 事件追踪'),
          bottom: const TabBar(
            tabs: [
              Tab(icon: Icon(Icons.apps), text: '进程监控'),
              Tab(icon: Icon(Icons.folder), text: '文件监控'),
            ],
          ),
        ),
        body: TabBarView(
          children: [_buildProcessMonitorTab(), _buildFileMonitorTab()],
        ),
      ),
    );
  }

  Widget _buildProcessMonitorTab() {
    return Column(
      children: [
        _buildControlPanel(
          isActive: _isProcessMonitoringActive,
          onToggle: _toggleProcessMonitoring,
          onClear: _clearProcessEvents,
          title: '进程监控',
          eventCount: _processEvents.length,
        ),
        Expanded(
          child: _processEvents.isEmpty
              ? const Center(
                  child: Text(
                    '暂无事件\n点击上方按钮开始监控',
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.grey, fontSize: 16),
                  ),
                )
              : ListView.builder(
                  itemCount: _processEvents.length,
                  itemBuilder: (context, index) {
                    final event = _processEvents[index];
                    return _buildProcessEventItem(event);
                  },
                ),
        ),
      ],
    );
  }

  Widget _buildFileMonitorTab() {
    return Column(
      children: [
        _buildControlPanel(
          isActive: _isFileMonitoringActive,
          onToggle: _toggleFileMonitoring,
          onClear: _clearFileEvents,
          title: '文件监控',
          eventCount: _fileEvents.length,
        ),
        Expanded(
          child: _fileEvents.isEmpty
              ? const Center(
                  child: Text(
                    '暂无事件\n点击上方按钮开始监控',
                    textAlign: TextAlign.center,
                    style: TextStyle(color: Colors.grey, fontSize: 16),
                  ),
                )
              : ListView.builder(
                  itemCount: _fileEvents.length,
                  itemBuilder: (context, index) {
                    final event = _fileEvents[index];
                    return _buildFileEventItem(event);
                  },
                ),
        ),
      ],
    );
  }

  Widget _buildControlPanel({
    required bool isActive,
    required VoidCallback onToggle,
    required VoidCallback onClear,
    required String title,
    required int eventCount,
  }) {
    return Container(
      padding: const EdgeInsets.all(16),
      color: Colors.grey[100],
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            children: [
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      title,
                      style: const TextStyle(
                        fontSize: 18,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                    const SizedBox(height: 4),
                    Text(
                      '状态: ${isActive ? "运行中" : "已停止"} | 事件数: $eventCount',
                      style: TextStyle(color: Colors.grey[600], fontSize: 12),
                    ),
                  ],
                ),
              ),
              const SizedBox(width: 8),
              ElevatedButton.icon(
                onPressed: onToggle,
                icon: Icon(isActive ? Icons.stop : Icons.play_arrow),
                label: Text(isActive ? '停止' : '开始'),
                style: ElevatedButton.styleFrom(
                  backgroundColor: isActive ? Colors.red : Colors.green,
                  foregroundColor: Colors.white,
                ),
              ),
              const SizedBox(width: 8),
              IconButton(
                onPressed: onClear,
                icon: const Icon(Icons.delete_outline),
                tooltip: '清除记录',
              ),
            ],
          ),
          if (!isActive)
            const Padding(
              padding: EdgeInsets.only(top: 8),
              child: Text(
                '⚠️ 需要管理员权限才能启动监控',
                style: TextStyle(color: Colors.orange, fontSize: 12),
              ),
            ),
        ],
      ),
    );
  }

  Widget _buildProcessEventItem(ProcessEvent event) {
    final dateFormat = DateFormat('HH:mm:ss.SSS');
    final time = DateTime.fromMillisecondsSinceEpoch(
      event.timestamp ~/ 10000, // Windows FILETIME 转换为毫秒
      isUtc: true,
    ).toLocal();

    final isStart = event.type == ProcessEventType.started;

    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: isStart ? Colors.green : Colors.red,
          child: Icon(
            isStart ? Icons.play_arrow : Icons.stop,
            color: Colors.white,
          ),
        ),
        title: Text(
          event.executablePath,
          style: const TextStyle(fontWeight: FontWeight.bold),
        ),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('PID: ${event.processId}'),
            Text('父进程 ID: ${event.parentProcessId}'),
            Text(
              dateFormat.format(time),
              style: TextStyle(fontSize: 10, color: Colors.grey[500]),
            ),
          ],
        ),
        trailing: Chip(
          label: Text(
            isStart ? '启动' : '终止',
            style: const TextStyle(fontSize: 11),
          ),
          backgroundColor: isStart ? Colors.green[100] : Colors.red[100],
        ),
      ),
    );
  }

  Widget _buildFileEventItem(FileEvent event) {
    final dateFormat = DateFormat('HH:mm:ss.SSS');
    final time = DateTime.fromMillisecondsSinceEpoch(
      event.timestamp ~/ 10000, // Windows FILETIME 转换为毫秒
      isUtc: true,
    ).toLocal();

    final typeInfo = _getFileEventTypeInfo(event.type);

    return Card(
      margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
      child: ListTile(
        leading: CircleAvatar(
          backgroundColor: typeInfo.$2,
          child: Icon(typeInfo.$1, color: Colors.white, size: 20),
        ),
        title: Text(
          event.filePath.split('\\').last,
          style: const TextStyle(fontWeight: FontWeight.bold),
          maxLines: 1,
          overflow: TextOverflow.ellipsis,
        ),
        subtitle: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              event.filePath,
              style: TextStyle(fontSize: 11, color: Colors.grey[600]),
              maxLines: 1,
              overflow: TextOverflow.ellipsis,
            ),
            Text('PID: ${event.processId}'),
            Text(
              dateFormat.format(time),
              style: TextStyle(fontSize: 10, color: Colors.grey[500]),
            ),
          ],
        ),
        trailing: Chip(
          label: Text(typeInfo.$3, style: const TextStyle(fontSize: 11)),
          backgroundColor: typeInfo.$2.withOpacity(0.2),
        ),
      ),
    );
  }

  (IconData, Color, String) _getFileEventTypeInfo(FileEventType type) {
    switch (type) {
      case FileEventType.created:
        return (Icons.add_circle, Colors.green, '创建');
      case FileEventType.deleted:
        return (Icons.delete, Colors.red, '删除');
      case FileEventType.modified:
        return (Icons.edit, Colors.blue, '修改');
      case FileEventType.renamed:
        return (Icons.drive_file_rename_outline, Colors.orange, '重命名');
    }
  }
}
1
likes
150
points
--
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for Windows that uses ETW (Event Tracing for Windows) to monitor process and file system activities in real-time.

Repository (GitHub)
View/report issues

Topics

#windows #etw #monitoring #process #filesystem

Documentation

API reference

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on event_tracing_windows

Packages that implement event_tracing_windows