On Terminal Servers, normal users cannot write to HKCU\Software\
Policies. Now also writes to HKCU\Software\Microsoft\Office\...\
Security which is always writable and also read by Outlook.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Apply to both 16.0 (2016-2024/365) and 15.0 (2013) registry
paths. Costs nothing and ensures it works regardless of which
Office version is installed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Main window wider (830px) so all buttons fit without resizing
- Set ALL Outlook Object Model Guard registry values (not just 3)
- Clean removal: delete entire Security subkey when disabling
- Add hint in settings that Outlook restart is needed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New setting "Outlook-Sicherheitsabfrage automatisch erlauben"
sets registry keys under HKCU\Policies\Microsoft\Office\16.0\
Outlook\Security to auto-approve Object Model Guard prompts.
Applied at app startup and when saving settings. Disabling the
option removes the registry values (back to Outlook default).
Works with all Outlook versions (2016-2024, same registry path).
No admin rights needed (HKCU).
Outlook must be restarted after changing this setting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- "Ueber" menu item in tray context menu opens About dialog
- New user setting "Beim Start automatisch synchronisieren"
syncs all enabled profiles once at app startup
- Sync lock prevents concurrent sync runs (timer, manual,
on-start cannot overlap - second request is skipped)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Include tags in PUT request (Starface may require it)
- Log failed updates with status code and response body
- Also committed: SafeGet for Outlook COM property reading
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dynamic COM with ?? operator can fail silently for properties
that return COM null vs .NET null. Use GetType().InvokeMember()
which reliably reads any Outlook property and catches COM errors
per field instead of crashing the whole contact read.
Fixes Fax and other fields that may not have been read correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fax and HomePhone are now checked for compatibility (filled on
one side, empty on other = different contacts)
- Fax number can serve as a strong match together with Company
- Prevents fax-only contacts from being missed or mismatched
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New matching logic checks ALL identifying fields for compatibility:
- Empty vs filled field = different contacts (not a match)
- Both empty = compatible (ignored for matching)
- Both filled = must be equal
Fields checked: Email, FirstName, LastName, Company, PhoneWork,
PhoneMobile. Requires at least one strong match (email, name,
or phone) plus no conflicting fields.
Example: Two "Max Mustermann" where one has Company="Firma A"
and the other has empty Company are now correctly identified as
different contacts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a mapped contact is deleted on one side, delete it on the
other side too (respecting sync direction setting):
- Deleted in Outlook -> delete in Starface (if direction allows)
- Deleted in Starface -> delete in Outlook (if direction allows)
- Deleted on both sides -> just remove the mapping
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When editing a profile and switching to a different Starface
address book, the old contact mappings are invalid (different
Starface IDs). Now automatically clears mappings and shows a
notification. Custom address books are already listed as tags.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Starface requires every contact to be assigned to a tag.
- Load tag IDs when fetching address books (folder/all for central,
folder/private for personal)
- Include tags array in POST /contacts body
- Debug log all discovered tags for troubleshooting
Important: Existing profiles need to reload address books (edit
profile -> load address books -> save) to pick up the tag IDs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Generated programmatically, no external ICO file needed.
Blue rounded square with white person silhouette and green/yellow
sync arrows. Used for main window title bar and system tray.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SetupTrayIcon was called on every RefreshProfileList, creating
a new NotifyIcon each time. Split into SetupTrayIcon (once) and
UpdateTrayMenu (on refresh).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Log the full request body and response when POST /contacts fails
so we can see why new contacts are not being created.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deletes all contact mappings and resets LastSync timestamp.
Next sync will re-match all contacts fresh without creating
duplicates (thanks to the duplicate detection in sync engine).
No contacts are deleted on either side.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three-phase sync approach:
1. Process existing mappings (detect changes on both sides,
handle conflicts with configurable winner)
2. Sync unmapped Outlook contacts to Starface with duplicate
check (match by email, name+company, name, phone)
3. Sync unmapped Starface contacts to Outlook with duplicate check
Key improvements:
- Duplicate detection before creating: checks email, name+company,
name, and phone number with normalization
- Matched duplicates get linked instead of re-created
- Conflict resolution when both sides changed
- Dead mappings (both sides deleted) get cleaned up
- Each contact logged individually with direction indicator
- Address book switch works: old mappings get cleaned, contacts
re-matched against new book
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Read mapping: Match by 'name' field instead of 'displayKey' because
many fields use USER_DEFINED as displayKey (street, city, state,
comment). Actual name fields: firstname, familyname, company, phone,
mobile, homephone, fax, e-mail, url, comment, street, city, postcode,
state, country.
Write mapping: Use correct 4-block structure (contact, address,
telephone, email) with proper resourceKey values matching the
Starface internal format.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The contacts list endpoint only returns summaryValues/phoneNumbers.
Now fetch each contact individually via GET /contacts/{id} to get
all fields (blocks/attributes). Also log the detail JSON structure
so we can verify the field mapping is correct.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Logs the first contact from Starface API response into the sync
log so we can see the actual JSON structure and fix field mapping.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Starface API:
- Handle both array and object responses from /contacts endpoint
- Try common wrapper fields (items, contacts, data, results)
Outlook contacts:
- Add FindFolderByPath that matches exact FolderPath property
- Fallback to Namespace.Folders navigation if store lookup fails
- Fallback: try reading contact fields even if Class != 40
- Add debug logging for folder path and item count
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The NuGet package Microsoft.Office.Interop.Outlook v15 tried to
load Office v15 PIA which fails on Office 2016/2019/2024 (v16).
Switch to dynamic COM (late binding) which works with ANY Outlook
Classic version without needing a specific Interop DLL. All Outlook
properties and methods are accessed via dynamic dispatch.
Also use 1-based COM collection indexing instead of foreach to
avoid COM enumerator issues.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Try GetActiveObject first, then Activator.CreateInstance as fallback
- Use Type.GetTypeFromProgID for version-independent COM activation
- Clear error message explaining possible causes including New Outlook
- NuGet Interop v15 is fine - it's the assembly version, works with
all Outlook versions (2013-2024) via COM interface compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Scan all stores recursively instead of only the default folder
- Properly release COM objects to avoid leaks
- Better error handling with debug output per store/folder
- Show error message if Outlook is not reachable
- Fallback to default contacts folder if recursive scan finds nothing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace Outlook folder ComboBox with TextBox + Browse button
that opens a TreeView-based folder browser dialog
- Add per-user settings stored in %AppData% (not HKLM)
with option to start minimized (System Tray only)
- Add Settings button to main window
- Settings are per-user, independent of profiles
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Important for Terminal Server / multi-user environments where
the setup is run once by an admin.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>