- .NET 8 SDK or later
- Windows 10/11 (for development and testing)
- Visual Studio 2022 or Visual Studio Code (recommended)
git clone https://github.com/Daolyap/Money-Shot.git
cd Money-Shotdotnet restore MoneyShot/MoneyShot.csproj# Debug build
dotnet build MoneyShot/MoneyShot.csproj --configuration Debug
# Release build
dotnet build MoneyShot/MoneyShot.csproj --configuration Releasedotnet run --project MoneyShot/MoneyShot.csprojHandles screen capture functionality:
CaptureFullScreen()- Captures all screensCaptureRegion(Rectangle)- Captures specific regionCaptureScreen(int)- Captures single screen by index
Manages saving screenshots:
SaveToClipboard(BitmapSource)- Copies to clipboardSaveToFile(BitmapSource, string, string)- Saves to fileSaveImage(BitmapSource, SaveDestination, string, string)- Combined save
Handles application settings:
LoadSettings()- Loads user settings from JSONSaveSettings(AppSettings)- Saves settings to JSONSetStartupWithWindows(bool)- Configures Windows startup
Manages global keyboard shortcuts:
RegisterHotKey(modifiers, key, action)- Registers hotkeyUnregisterHotKey(id)- Removes hotkey- Uses Win32 API for global hotkey registration
Main application interface:
- System tray integration
- Capture mode selection
- Settings access
- About information
Screenshot annotation editor:
- Toolbar with annotation tools
- Color picker
- Canvas for drawing
- Save/copy functionality
Full-screen overlay for region selection:
- Click and drag to select area
- Visual feedback with red rectangle
- ESC to cancel
Configuration interface:
- Save destination preferences
- File path and format selection
- Startup options
- Tray behavior
dotnet publish MoneyShot/MoneyShot.csproj \
--configuration Release \
--output ./publish \
--runtime win-x64 \
--self-contained falsedotnet publish MoneyShot/MoneyShot.csproj \
--configuration Release \
--output ./publish \
--runtime win-x64 \
--self-contained true \
-p:PublishSingleFile=true \
-p:PublishTrimmed=trueThe project includes automated CI/CD workflows:
-
Build and Release (
.github/workflows/release.yml)- Triggers automatically on every push to main/master branch
- Builds both portable ZIP and MSI installer
- Creates a GitHub release automatically with:
- Version tag:
v{version}-build.{build_number}.{commit_sha} - Both MSI and ZIP artifacts attached
- Generated release notes
- Version tag:
- Marked as pre-release for development builds
- Versioning: Build number is synchronized across all artifacts:
- Assembly version:
{version}.{build_number}(e.g.,1.0.0.123) - File version:
{version}.{build_number} - MSI version:
{version}.{build_number}
- Assembly version:
-
Build (
.github/workflows/build.yml)- Runs on pull requests for validation
- Creates build artifacts for review
- Ensures code builds successfully before merge
- Uses build number for version synchronization
-
Build MSI Installer (
.github/workflows/build-msi.yml)- Runs on pull requests for validation
- Tests MSI installer creation
- Can be manually triggered via workflow_dispatch
- Uses build number for MSI version
Releases are fully automated:
- Every merge to main/master triggers a new release
- Version is extracted from
MoneyShot/MoneyShot.csproj - Build number from
GITHUB_RUN_NUMBERis appended to assembly and file versions - MSI installer version matches the executable version
- Build artifacts are automatically uploaded to GitHub Releases
- Users can download the latest build from the Releases page
To ensure consistency, the build number is synchronized across:
- Git Tag:
v1.0.0-build.123.abc1234 - Assembly Version:
1.0.0.123 - File Version:
1.0.0.123 - MSI Version:
1.0.0.123
This is achieved by:
- Extracting the base version from
MoneyShot.csproj - Passing
/p:AssemblyVersionand/p:FileVersiontodotnet build - Passing
-d ProductVersionto the WiX toolset during MSI creation
- Add enum value to
Models/AnnotationTool.cs:
public enum AnnotationTool
{
// ... existing tools
YourNewTool
}- Add button to
Views/EditorWindow.xaml:
<Button Content="🎨 Your Tool" Tag="YourNewTool" Click="ToolButton_Click" ... />- Implement tool logic in
Views/EditorWindow.xaml.cs:
private Shape CreateYourTool()
{
// Create and return your shape
}- Add case to tool switch in
Canvas_MouseDown:
AnnotationTool.YourNewTool => CreateYourTool(),- Add property to
Models/AppSettings.cs:
public YourType YourSetting { get; set; } = defaultValue;-
Add UI control to
Views/SettingsWindow.xaml -
Load/save in
Views/SettingsWindow.xaml.cs:
// In LoadSettings()
YourControl.Value = _settings.YourSetting;
// In Save_Click()
_settings.YourSetting = YourControl.Value;Set breakpoints in Visual Studio or use debug logging:
#if DEBUG
System.Diagnostics.Debug.WriteLine("Your debug message");
#endifHotkeys not working:
- Check if another application is using the same hotkey
- Ensure the window has been initialized before registering hotkeys
Screenshots appear black:
- Some applications use protected rendering
- Try capturing the entire screen instead
High DPI issues:
- Application manifest includes DPI awareness settings
- Test on different DPI scaling levels
- Full screen capture works on all monitors
- Region selection captures correct area
- All annotation tools draw correctly
- Colors change when selected
- Undo works for all tools
- Save to clipboard works
- Save to file works
- Settings persist across restarts
- Hotkeys trigger captures
- System tray menu works
- Startup integration works
- Screenshots are captured using GDI+ for maximum compatibility
- Large screenshots (multi-4K monitors) may take time to capture
- Annotation rendering uses WPF hardware acceleration when available
- No telemetry or data collection
- Settings stored locally in AppData
- No network requests
- Registry modifications only for startup integration (with user consent)
- Use C# 12 features where appropriate
- Follow Microsoft naming conventions
- Use nullable reference types
- Document public APIs with XML comments
- Keep methods focused and single-purpose
See the roadmap in README.md for planned features.
- Check existing issues on GitHub
- Review this documentation
- Examine the code - it's well-structured and commented
- Open a new issue if you're stuck