A .NET 8.0 Windows Service that syncs customers, items, and invoices between QuickBooks Desktop and a web application via SignalR.
- The service connects to your web application's SignalR hub
- When the web app sends a
SyncQuickBookscommand, the service reads customers and items from QuickBooks Desktop and posts them to the web app's API - When the web app sends a
SendTicketsToQBcommand, the service creates invoices in QuickBooks from ticket data - When QuickBooks is not running, the service reports the error back to the web app
- Two-way sync: Read customers/items from QB, create invoices in QB
- Auto-reconnect: Never stops trying to reconnect (exponential backoff: 2s, 5s, 10s, 30s max)
- Windows Service: Runs in the background, starts with Windows
- COM Interop: Communicates with QuickBooks Desktop via QBXMLRP2
- Error reporting: Alerts the web UI when QuickBooks is not running
- Tons calculation: Converts net weight (lbs) to tons for QB invoices
Run PowerShell as Administrator:
git clone https://github.com/GTMichelli-Dev/qb-sync-service.git C:\temp\qbs
.\C:\temp\qbs\deploy\install.ps1 -WebServerUrl "https://basicscale.scaledata.net"
Remove-Item -Recurse -Force C:\temp\qbsWith options:
git clone https://github.com/GTMichelli-Dev/qb-sync-service.git C:\temp\qbs
.\C:\temp\qbs\deploy\install.ps1 -WebServerUrl "https://basicscale.scaledata.net" `
-ServiceName "QBSync-Plant1"
Remove-Item -Recurse -Force C:\temp\qbs| Parameter | Default | Description |
|---|---|---|
-WebServerUrl |
(required) | BasicWeigh web server URL |
-ServiceName |
QBSyncService |
Windows service name |
-InstallDir |
C:\Services\QBSyncService |
Install location |
-Branch |
master |
Git branch to install |
-Uninstall |
Remove the service and files |
What the script does:
- Checks for .NET SDK (required — install via
winget install Microsoft.DotNet.SDK.8if missing) - Checks for QuickBooks Desktop
- Clones and builds the service from GitHub
- Configures the web server URL
- Installs as a Windows Service with auto-restart on failure
- Starts the service
Prerequisites: .NET 8 SDK and QuickBooks Desktop must be installed. The script checks for both and warns if missing.
To update: Run the same command again. The script stops the service, rebuilds, and restarts.
# Build
dotnet publish -c Release -o C:\Services\QBSyncService
# Install as Windows Service
sc create "QBSyncService" binPath="C:\Services\QBSyncService\QBSyncService.exe"
sc start QBSyncServicedotnet runEdit appsettings.json:
{
"QBSync": {
"ServerUrl": "http://localhost:5110",
"CompanyFilePath": "",
"QBAppName": "BasicWeigh"
}
}| Setting | Description |
|---|---|
ServerUrl |
URL of the web application with the SignalR hub |
CompanyFilePath |
Path to the QB company file. Leave empty to use the currently open file |
QBAppName |
Application name registered with QuickBooks |
- Windows (QuickBooks Desktop is Windows-only)
- .NET 8.0 SDK (for building) or Runtime (for running)
- QuickBooks Desktop installed on the same machine
- QuickBooks must authorize the app on first run
On first run, QuickBooks will prompt you to allow access:
- Make sure QuickBooks Desktop is running with a company file open
- When prompted, select "Yes, always" to allow the service
- The service will appear in QB under Edit > Preferences > Integrated Applications
# Check status
sc query QBSyncService
# Start / Stop
sc start QBSyncService
sc stop QBSyncService
# View logs
Get-EventLog -LogName Application -Source QBSyncService -Newest 20
# Uninstall
.\deploy\install.ps1 -WebServerUrl "unused" -UninstallYour web application must implement these hub methods:
| Direction | Method | Description |
|---|---|---|
| Server -> Service | SyncQuickBooks |
Read customers/items from QB |
| Server -> Service | SendTicketsToQB(ticketJson) |
Create invoices in QB |
| Service -> Server | JoinQBSyncGroup() |
Register in the QB sync group |
| Service -> Server | SyncComplete(resultJson) |
Return sync results |
| Service -> Server | SyncStatus(message) |
Report progress |
| Service -> Server | QBNotRunning(message) |
Report QB not available |
The service posts sync data to:
POST /api/masterdata/sync/customers - Upsert customers from QB
POST /api/masterdata/sync/commodities - Upsert items/commodities from QB
POST /api/transactions/mark-sent-to-qb - Mark tickets as sent after invoice creation