一个轻量的 Windows 桌面日程小组件,纯 C + Win32 API + GDI+ 编写,无任何运行时依赖(静态链接 /MT,单个 exe 即可运行)。常驻桌面右下角,提供月历、当日议程、定时提醒与日程文件导入。
- 想看日程却不想开 App:日历/待办软件启动慢、弹窗多;本组件直接钉在桌面层,随时瞟一眼就能看到月历与当天安排,收起后只是一枚小胶囊。
- 已有日程分散在各处:日历(.ics)、Excel/表格(.xlsx/.csv)、自建脚本(.json)里的日程可以一次性导入,不必手动重录。
- 怕错过、也怕被打扰:可按日程设置提前提醒;不想要常驻窗口时可折叠成胶囊自动轮播。
- 讨厌安装依赖:单 exe、无 .NET/无运行库、数据全在本地,拷走即迁移。
- 月历视图:标记有日程的日期,高亮今天与选中日,左右翻月,「今」一键回到今日。
- 当日议程:按时间列出当天所有日程,长列表可滚动。
- 收起态 pill:可折叠成小胶囊,自动轮播当天日程;鼠标悬停显示完整备注,滚轮可手动切换。
- 定时提醒:可设置日程开始前提醒,到点系统弹窗通知。
- 循环日程:支持按天 / 周 / 月 / 年等周期重复。
- 自动清理过期日程:启动时与运行中每 60 秒巡检;循环事件永不删除,全天事件在结束日次日才移除。
- 文件导入:支持
.ics/.csv/.xlsx/.json,可选择「覆盖」或「追加」,也可拖放文件导入。 - 多语言界面:支持 中文 / English (US) / English (UK),默认跟随系统;设置中切换后即时生效(日期格式、12/24 小时制、每周起始日随语言习惯变化)。
- 开机自启、单实例运行、高 DPI 自适应、深色主题。
schedule/
├── src/ 全部源码与资源(.c/.h/.rc/.ico/.manifest)
├── third_party/cJSON/ 第三方 JSON 解析库(MIT,含 LICENSE)
├── tools/ 自测程序与测试构建脚本
├── build.bat 一键构建脚本(自动探测 MSVC)
├── LICENSE 项目许可(MIT)
├── .clangd clangd 编辑器配置
├── compile_flags.txt clangd 编译标志
└── .gitignore
- Windows 10 / 11(x64)
- Visual Studio 2019 或更高版本(需勾选「使用 C++ 的桌面开发」,提供 MSVC 编译器与 Windows SDK)
- 也支持仅安装 Visual Studio Build Tools。
- 构建脚本会通过
vswhere自动查找 VS 安装路径,无需手工配置;命令行构建不依赖 IDE。
在项目根目录双击或在命令行执行:
build.bat成功后产物位于:
release\ScheduleWidget.exe
直接双击该 exe 即可运行(无需安装、无需附带 dll)。
如果脚本提示找不到 vcvars64.bat,请确认已安装 MSVC C++ 工具链;也可在「x64 Native Tools Command Prompt for VS」中手动执行
build.bat。
从 GitHub Releases 用浏览器下载的 ScheduleWidget.exe 会被 Windows 标记为「来自 Internet」(Mark-of-the-Web)。由于本项目没有购买代码签名证书,首次运行未签名、尚无信誉记录的新文件时,SmartScreen 可能显示「Windows 已保护你的电脑」。这不是病毒告警:源码公开、可自行构建,Release 同时提供 SHA256SUMS.txt 供校验。
任选一种方式运行:
- 直接运行:点「更多信息」→「仍要运行」。
- 先解除锁定(推荐,只需一次):右键 exe → 属性 → 勾选「解除锁定」→ 确定;或在 PowerShell 中执行:
仓库也提供脚本:
Unblock-File .\ScheduleWidget.exe
powershell -ExecutionPolicy Bypass -File tools\unblock.ps1 -Path .\ScheduleWidget.exe
- 命令行下载(不产生 Mark-of-the-Web):
已安装 GitHub CLI 时也可以:
Invoke-WebRequest -Uri https://github.com/Rcyc-1025/ScheduleWidget/releases/latest/download/ScheduleWidget.exe -OutFile ScheduleWidget.exe Unblock-File .\ScheduleWidget.exe .\ScheduleWidget.exe
gh release download --repo Rcyc-1025/ScheduleWidget --pattern ScheduleWidget.exe
- 从源码构建:
build.bat生成的本地文件不会被标记。
校验下载文件:
Get-FileHash .\ScheduleWidget.exe -Algorithm SHA256彻底消除「下载后首次运行」的提示只有两条路:使用受信任的代码签名证书(新证书仍需积累信誉,首次下载也可能提示),或上架 Microsoft Store。未签名的 exe 无法保证浏览器下载后零提示;不建议为了单个程序关闭系统级 SmartScreen。
运行后窗口出现在屏幕右下角,右键窗口或点击右上角「⋯」打开菜单:
| 操作 | 说明 |
|---|---|
| 新建日程 | 编辑标题、日期/时间、备注、颜色、提醒、重复规则 |
| 导入日程文件… | 选择或拖入 ics/csv/xlsx/json;已有日程时可选覆盖或追加 |
| 导出日程… | 导出为 JSON 备份 |
| 恢复备份(JSON)… | 从之前导出的 JSON 恢复 |
| 开机自启 | 切换登录 Windows 后自动运行 |
| 清除所有日程 | 清空(不可撤销,操作前建议先导出备份) |
交互细节:
- 收起态:点击「—」折叠为胶囊;悬停可看完整备注,滚轮上下切换当天不同日程。
- 回到今日:翻到其他月份或选中其他日期后,月份行会出现「今」按钮,点击即回到今天。
- **导入窗口的「示范文件」**按钮会生成 4 种格式的示例文件,可对照格式编辑后再导入。
- CSV:建议表头为
日期,时间,标题,备注(表头可识别中英文,列顺序不限);时间列留空即视为全天日程;兼容 UTF-8 BOM。 - XLSX:按第一张工作表、与 CSV 相同的列约定解析。
- ICS:标准 iCalendar(iCal)格式。
- JSON:日程数组,或
{"events":[...]}/{"items":[...]};字段支持date/time/title/note,也兼容start/summary/description等常见命名。
输入 — CSV(日程示范.csv,UTF-8 带 BOM;时间留空 = 全天):
日期,时间,标题,备注
2026-09-21,,项目评审,3 楼会议室
2026-09-21,14:30,团队午餐,餐厅二楼
2026-10-06,09:00,季度汇报,会议室 A输入 — ICS(日程示范.ics,VALUE=DATE 为全天日程):
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//ScheduleWidget//Sample//CN
BEGIN:VEVENT
UID:sample-1@schedulewidget
DTSTAMP:20260101T000000Z
DTSTART;VALUE=DATE:20260921
SUMMARY:项目评审
DESCRIPTION:3 楼会议室
END:VEVENT
END:VCALENDAR输入 — JSON(日程示范.json):
[
{ "date": "2026-09-21", "title": "项目评审", "desc": "3 楼会议室" },
{ "date": "2026-09-21", "time": "14:30", "title": "团队午餐", "desc": "餐厅二楼" }
]输出 — 导出/备份 JSON(「导出日程…」生成的 schedule.json 结构,导入 .json 时也兼容此格式):
{
"events": [
{
"id": "8f3c…",
"title": "团队午餐",
"note": "餐厅二楼",
"start": "2026-09-21T14:30",
"end": "2026-09-21T15:30",
"allDay": false,
"color": 2,
"remind": 30,
"rec": "none",
"interval": 1,
"unit": "day",
"until": ""
},
{
"id": "a1d9…",
"title": "项目评审",
"note": "3 楼会议室",
"start": "2026-09-21",
"end": "2026-09-21",
"allDay": true,
"color": 0,
"remind": -1,
"rec": "weekly",
"interval": 1,
"unit": "week",
"until": "2026-12-31"
}
]
}字段说明:定时事件 start/end 为 YYYY-MM-DDTHH:MM;全天事件为纯日期 YYYY-MM-DD(end 含当天);remind 为提前分钟数(-1 不提醒);rec ∈ none/daily/weekly/monthly/yearly/custom;unit ∈ minute/hour/day/week/month/year(rec 为 custom 时与 interval 搭配使用)。
输出 — 界面显示(中文 / English (US) 的格式差异):
| 场景 | 中文 | English (US) |
|---|---|---|
| 定时日程胶囊(未来) | 9月21日 14:30 · 30分钟后 |
9/21 2:30 PM · in 30 minutes |
| 全天日程胶囊(无备注) | 9月21日 · 3天后 |
9/21 · in 3 days |
| 议程时间范围(同日定时) | 14:30 – 15:30 |
2:30 PM – 3:30 PM |
| 全天跨日范围 | 全天 · 9月21日 ~ 9月22日 |
All day · 9/21 ~ 9/22 |
English (UK) 与中文同为 24 小时制与周一起始,日期为
21/9/2026风格;English (US) 为 12 小时制、周日起始。
点导入窗口的「示范文件」按钮可一键生成这四种格式的真实文件(中英文内容随界面语言自动切换),直接对照编辑即可。
- 导入 .doc / .xls 没反应? 旧版二进制格式不支持,请先另存为
.docx/.xlsx/.csv再导入。 - CSV 导入后标题/备注错位? 请确认首行为表头(
日期,时间,标题,备注或date,time,title,note),文件保存为 UTF-8(带 BOM 更稳)。 - 误清空了日程怎么办? 「清除所有日程」不可撤销;养成定期「导出日程…」备份的习惯,恢复用「恢复备份(JSON)…」。
- 窗口被其他窗口挡住? 组件钉在桌面层(壁纸之上、普通窗口之下),正常使用不受影响;在「显示桌面」后它会再次露出。
- 换了语言没全部生效? 菜单、气泡即时切换;已打开的导入窗口需关闭后重新打开。
所有数据保存在当前用户目录,卸载/删除 exe 不会自动清除:
%APPDATA%\ScheduleWidget\
├── schedule.json 日程数据({"events":[...]})
└── settings.json 设置(开机自启、语言、默认提醒等)
如需迁移或备份,直接复制整个 ScheduleWidget 文件夹即可。
tools/ 下包含 6 套自测(导入解析、全天事件、过期清理、xlsx 文本抽取、示范文件生成、农历换算)。例如:
tools\build_test.bat test_purge build\util.obj build\lang.obj脚本会自动编译并运行对应测试,输出 ALL PASS 即通过;第 2 个及之后的参数是要一起链接的主工程 obj(先执行一次 build.bat 生成)。各测试所需 obj:
| 测试 | 额外 obj |
|---|---|
| test_import | build\lang.obj build\util.obj |
| test_purge / test_allday | build\util.obj build\lang.obj |
| test_extract / test_samples | build\text_extract.obj build\lang.obj build\util.obj |
| test_lunar | 无 |
- cJSON(MIT License),见
third_party/cJSON/LICENSE。
本项目源码以 MIT License 发布,Copyright (c) 2026 Rcyc-1025,完整文本见根目录 LICENSE。
- 可自由使用、修改、分发(含商用与闭源),需在副本或重要部分中保留版权与许可声明。
- 本项目不提供任何担保,作者不承担因使用产生的任何责任。
A lightweight Windows desktop schedule widget written in pure C + Win32 API + GDI+, with zero runtime dependencies (statically linked /MT, runs as a single exe). Pinned to the bottom-right corner of your desktop, it provides a monthly calendar, daily agenda, timed reminders, and schedule file import.
- Want to check your schedule without opening an app: Calendar/todo apps are slow to launch and cluttered with popups; this widget sits on the desktop layer — just glance at the calendar and today's agenda anytime, and it collapses into a tiny pill when not needed.
- Schedules scattered across sources: Import everything at once from iCal (.ics), Excel/spreadsheets (.xlsx/.csv), or your own scripts (.json) — no manual re-entry.
- Afraid of missing things, but also afraid of being disturbed: Set advance reminders per event; collapse the window into a pill that auto-rotates today's schedule.
- Tired of install dependencies: Single exe, no .NET / no runtime libraries, all data stored locally — just copy and go.
- Calendar view: Marks dates with events, highlights today and selected day, prev/next month navigation, "Today" button to jump back.
- Daily agenda: Lists all events for the selected day in time order; long lists scroll.
- Collapsed pill: Fold into a compact pill that auto-rotates today's events; hover to see full notes, scroll wheel to switch manually.
- Timed reminders: Set advance reminders before event start; system toast notification at the scheduled time.
- Recurring events: Support for daily / weekly / monthly / yearly / custom interval recurrence.
- Auto-cleanup of expired events: Checked at startup and every 60 seconds; recurring events are never deleted, all-day events are removed the day after they end.
- File import: Supports
.ics/.csv/.xlsx/.json; choose "overwrite" or "append"; drag-and-drop supported. - Multilingual UI: Supports Chinese / English (US) / English (UK), defaults to system language; switches instantly in settings (date format, 12/24-hour clock, week start day adapt to language).
- Autostart, single-instance, high-DPI aware, dark theme.
schedule/
├── src/ All source code and resources (.c/.h/.rc/.ico/.manifest)
├── third_party/cJSON/ Third-party JSON parser (MIT, includes LICENSE)
├── tools/ Self-test programs and test build scripts
├── build.bat One-click build script (auto-detects MSVC)
├── LICENSE Project license (MIT)
├── .clangd clangd editor config
├── compile_flags.txt clangd compile flags
└── .gitignore
- Windows 10 / 11 (x64)
- Visual Studio 2019 or later (select "Desktop development with C++" for MSVC compiler and Windows SDK)
- Alternatively, install only Visual Studio Build Tools.
- The build script auto-detects the VS installation path via
vswhere; no manual configuration needed.
Double-click or run from the command line in the project root:
build.batThe output is located at:
release\ScheduleWidget.exe
Double-click the exe to run — no installation, no additional DLLs required.
If the script cannot find vcvars64.bat, ensure MSVC C++ toolchain is installed; you can also run
build.batmanually from "x64 Native Tools Command Prompt for VS".
An exe downloaded through a browser from GitHub Releases carries Mark-of-the-Web. Because this project does not have a code-signing certificate, the first run of an unsigned file with no reputation may trigger "Windows protected your PC". This is not a virus alert: the source is public, you can build it yourself, and each release includes SHA256SUMS.txt for verification.
Choose one:
- Run anyway: click "More info" → "Run anyway".
- Unblock once (recommended): right-click the exe → Properties → check "Unblock" → OK; or in PowerShell:
The repository also includes a helper script:
Unblock-File .\ScheduleWidget.exe
powershell -ExecutionPolicy Bypass -File tools\unblock.ps1 -Path .\ScheduleWidget.exe
- Command-line download (no Mark-of-the-Web):
With GitHub CLI installed:
Invoke-WebRequest -Uri https://github.com/Rcyc-1025/ScheduleWidget/releases/latest/download/ScheduleWidget.exe -OutFile ScheduleWidget.exe Unblock-File .\ScheduleWidget.exe .\ScheduleWidget.exe
gh release download --repo Rcyc-1025/ScheduleWidget --pattern ScheduleWidget.exe
- Build from source:
build.batproduces a local file without Mark-of-the-Web.
Verify the download:
Get-FileHash .\ScheduleWidget.exe -Algorithm SHA256The only ways to remove the first-run download prompt entirely are a trusted code-signing certificate (a new certificate still has to build reputation, so the first downloads may still warn) or Microsoft Store distribution. An unsigned exe cannot guarantee a zero-prompt browser download; do not disable system-wide SmartScreen for one app.
After launching, the window appears at the bottom-right corner of the screen. Right-click the window or click the "⋯" button in the top-right to open the menu:
| Action | Description |
|---|---|
| New Event | Edit title, date/time, note, color, reminder, recurrence rule |
| Import Schedule File… | Select or drag in ics/csv/xlsx/json; choose overwrite or append if events exist |
| Export Schedule… | Export as JSON backup |
| Restore Backup (JSON)… | Restore from a previously exported JSON |
| Autostart | Toggle auto-launch on Windows login |
| Clear All Events | Wipe all events (irreversible — export a backup first) |
Interaction tips:
- Collapsed state: Click "—" to fold into a pill; hover to see full notes, scroll wheel to switch between today's events.
- Back to today: After navigating to another month or selecting another date, a "Today" button appears in the month header — click to return.
- The "Sample Files" button in the import window generates 4 example files for each format — use them as templates.
- CSV: Recommended header
日期,时间,标题,备注ordate,time,title,note(headers are locale-aware, column order is flexible); empty time column = all-day event; UTF-8 BOM compatible. - XLSX: Parsed using the first worksheet, same column conventions as CSV.
- ICS: Standard iCalendar (iCal) format.
- JSON: Event array, or
{"events":[...]}/{"items":[...]}; fields supportdate/time/title/note, also compatible withstart/summary/descriptionand other common names.
Input — CSV (schedule_sample.csv, UTF-8 with BOM; empty time = all-day):
date,time,title,note
2026-09-21,,Project Review,3rd Floor Conference Room
2026-09-21,14:30,Team Lunch,2nd Floor Cafeteria
2026-10-06,09:00,Quarterly Report,Conference Room AInput — ICS (schedule_sample.ics, VALUE=DATE for all-day):
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//ScheduleWidget//Sample//EN
BEGIN:VEVENT
UID:sample-1@schedulewidget
DTSTAMP:20260101T000000Z
DTSTART;VALUE=DATE:20260921
SUMMARY:Project Review
DESCRIPTION:3rd Floor Conference Room
END:VEVENT
END:VCALENDARInput — JSON (schedule_sample.json):
[
{ "date": "2026-09-21", "title": "Project Review", "note": "3rd Floor Conference Room" },
{ "date": "2026-09-21", "time": "14:30", "title": "Team Lunch", "note": "2nd Floor Cafeteria" }
]Output — Export/Backup JSON (structure generated by "Export Schedule…"; also compatible with .json import):
{
"events": [
{
"id": "8f3c…",
"title": "Team Lunch",
"note": "2nd Floor Cafeteria",
"start": "2026-09-21T14:30",
"end": "2026-09-21T15:30",
"allDay": false,
"color": 2,
"remind": 30,
"rec": "none",
"interval": 1,
"unit": "day",
"until": ""
},
{
"id": "a1d9…",
"title": "Project Review",
"note": "3rd Floor Conference Room",
"start": "2026-09-21",
"end": "2026-09-21",
"allDay": true,
"color": 0,
"remind": -1,
"rec": "weekly",
"interval": 1,
"unit": "week",
"until": "2026-12-31"
}
]
}Field reference: timed events use start/end as YYYY-MM-DDTHH:MM; all-day events use plain date YYYY-MM-DD (end is inclusive); remind is minutes before start (-1 = no reminder); rec ∈ none/daily/weekly/monthly/yearly/custom; unit ∈ minute/hour/day/week/month/year (used with interval when rec is custom).
Output — UI Display (format differences between Chinese and English (US)):
| Scenario | Chinese | English (US) |
|---|---|---|
| Timed event pill (upcoming) | 9月21日 14:30 · 30分钟后 |
9/21 2:30 PM · in 30 minutes |
| All-day event pill (no note) | 9月21日 · 3天后 |
9/21 · in 3 days |
| Agenda time range (same day) | 14:30 – 15:30 |
2:30 PM – 3:30 PM |
| All-day multi-day range | 全天 · 9月21日 ~ 9月22日 |
All day · 9/21 ~ 9/22 |
English (UK) shares 24-hour clock and Monday-start week with Chinese, but uses
21/9/2026date format; English (US) uses 12-hour clock with Sunday-start week.
Click the "Sample Files" button in the import window to generate real example files in all four formats (content language follows the UI language).
- Can't import .doc / .xls files? Legacy binary formats are not supported — save as
.docx/.xlsx/.csvfirst. - CSV import shows misaligned columns? Ensure the first row is a header (
date,time,title,note), and the file is UTF-8 encoded (BOM recommended). - Accidentally cleared all events? "Clear All Events" is irreversible; make a habit of exporting backups regularly via "Export Schedule…", and restore with "Restore Backup (JSON)…".
- Window hidden behind other windows? The widget is pinned to the desktop layer (above wallpaper, below normal windows); it's normally unaffected, and reappears after "Show Desktop".
- Language switch not fully applied? Menus and notifications switch instantly; an already-open import window needs to be closed and reopened.
All data is stored in the current user's directory; uninstalling or deleting the exe does not auto-clean:
%APPDATA%\ScheduleWidget\
├── schedule.json Event data ({"events":[...]})
└── settings.json Settings (autostart, language, default reminder, etc.)
To migrate or back up, simply copy the entire ScheduleWidget folder.
The tools/ directory contains 6 self-test suites (import parsing, all-day events, expiry cleanup, xlsx text extraction, sample file generation, lunar calendar conversion). For example:
tools\build_test.bat test_purge build\util.obj build\lang.objThe script compiles and runs the test; "ALL PASS" means success. The 2nd and later arguments are main-project objs to link (run build.bat once first to generate them). Required objs per test:
| Test | Extra objs |
|---|---|
| test_import | build\lang.obj build\util.obj |
| test_purge / test_allday | build\util.obj build\lang.obj |
| test_extract / test_samples | build\text_extract.obj build\lang.obj build\util.obj |
| test_lunar | — |
- cJSON (MIT License), see
third_party/cJSON/LICENSE.
This project's source code is licensed under the MIT License, Copyright (c) 2026 Rcyc-1025. See the LICENSE file in the root directory for the full text.
- You are free to use, modify, and distribute (including commercially and in closed source), provided the copyright and license notices are retained in copies or substantial portions.
- This project is provided "as is" without any warranty; the author assumes no liability for damages arising from its use.