winform 开机启动

c# winform 写的采集程序。平时是登录 windows 桌面,手动点开运行 winform 程序。
但是要改成开机启动,不要登录 windows 桌面也能执行 winform 程序。有没有什么办法?不要改造 winform 程序

先说核心结论

WinForm 本身是依赖 Windows 会话(Desktop 桌面会话)的 GUI 程序,不登录 Windows 桌面(无用户会话)直接跑 WinForm 窗口,原生做不到,而且你要求【不改 WinForm 代码】,所以不能直接把这个 exe 注册成 Windows 服务。

Windows 服务运行在 Session 0,Session0没有桌面、不能渲染窗口,直接在服务里启动 WinForm 会报错 / 闪退,哪怕你代码不动也不行。

但有成熟方案,完全不用修改你现有的 WinForm 采集程序代码,实现:开机自动跑、不需要人登录桌面,采集程序后台正常工作。 下面给你 3 套可选方案,按推荐优先级排序:

方案 1:任务计划程序(推荐,最简单,不改程序)✅

原理:设置任务在计算机启动时触发,使用【不管用户是否登录都要运行】,配合自动登录或者用 winsta0 桌面会话

你的采集程序虽然是 WinForm,但很多工业采集程序,窗口只是 UI,业务逻辑(PLC、文件采集)在后台线程。只要业务逻辑不依赖窗口显示,就算窗口看不见,采集逻辑照样跑。

操作步骤

  1. 打开「任务计划程序」(taskschd.msc)
  2. 创建任务
  • 常规页:
    • 名称:采集程序
    • 安全选项:不管用户是否登录都要运行(重点)
    • 勾选【使用最高权限运行】
  • 触发器:新建 → 【计算机启动时】
  • 操作:新建 → 启动程序,选中你的 xxx.exe
  • 条件 / 设置按需调整

⚠️ 关键坑: 当选择【不管用户是否登录都要运行】,程序默认在非交互式会话,WinForm 窗口不会显示出来,但是程序进程是可以跑起来的。 👉 适合场景:采集逻辑独立,不需要人机交互,你平时只是打开看日志,不需要自动弹出窗口。 👉 验证:机器重启不登录,远程用任务管理器看进程是否存在,看采集日志有没有持续写入。

缺点:无法看到 WinForm 界面;如果你的采集业务必须依赖窗口句柄 / UI 控件(极少数),就会异常。

备选子方案:任务计划 + Windows 自动登录(能显示窗口)

如果你希望程序能完整弹出 WinForm 界面(需要桌面会话):

  1. 开启 Windows 自动登录,开机自动进指定账号桌面(不需要手动输密码登录)
  2. 任务计划触发器改成【当用户登录时】
  3. 机器上电 → 自动登录账号 → 自动启动你的 WinForm,完整显示窗口。

优点:程序和你手动点开一模一样,100% 原样运行; 缺点:系统会自动登录账号,有一定安全风险(工控机内网环境一般可接受)。

方案 2:写一个简易 Windows 服务(服务做 “启动器”,不改原有 WinForm)✅

服务本身不承载 WinForm,服务只负责监控开机,启动一个独立进程跑你的原有 WinForm.exe,代码完全不动。 但注意:Session0 隔离,服务直接启动 GUI 进程依然看不到窗口,分两种:

  1. 只需要采集后台跑,不需要窗口:服务启动 Process.Start 拉起你的 exe,进程在后台执行,采集逻辑正常。
  2. 需要桌面窗口:服务不能直接创建桌面 GUI,要额外代码调用 CreateProcessAsUser,把进程创建到登录用户的桌面会话(winsta0)。

你只需要写一个很小的 C# 服务项目(几十行代码,只是启动器),原来的采集 WinForm 项目一行代码不用改。 适合:需要开机后台托管,程序崩溃后服务可以自动重启你的采集 exe。

简易服务启动器核心示意(仅启动进程,不包含会话切换)

protected override void OnStart(string[] args)
{
    var psi = new ProcessStartInfo(@"D:\采集程序\YourApp.exe");
    psi.UseShellExecute = false;
    Process.Start(psi);
}

注意:不带会话提升版本,只能后台跑,看不到窗口;想要窗口,必须实现CreateProcessAsUser,这块代码有复杂度。

方案 3:第三方工具 NSSM(Non-Sucking Service Manager)【强烈推荐工控场景】✅

NSSM 是成熟开源工具,不用写一行服务代码,直接把任意 exe 包装成 Windows 服务,你的 WinForm 程序完全不用改。 本质:NSSM 本身是 Windows 服务,作为代理,去启动你的 exe。

使用要点

  1. 下载 NSSM(工控常用,轻量)
  2. 管理员 CMD 执行:nssm install 采集服务
  3. 在弹出窗口选择你的采集 xxx.exe
  4. 【Details】填写服务名
  5. 【Recovery】设置程序崩溃自动重启(工控非常有用)
  6. 安装完成,服务开机自动启动

⚠️ 同样 Session0 限制:

  • 默认:服务拉起的 WinForm没有桌面窗口,进程后台运行;适合只做采集写日志、和 PLC 通信。
  • 如果需要可见窗口:NSSM 本身不直接支持 Session0 跳转,还是要配合自动登录方案。

关键区分,帮你快速选方案

表格

需求推荐方案
只要求采集业务跑,不需要看到 WinForm 窗口,最简单部署任务计划程序(计算机启动时,不管用户是否登录运行)
需要程序崩溃自动重启,工业稳定优先,不需要界面NSSM 包装成服务
必须完整显示 WinForm 窗口,和手动打开效果完全一致Windows 自动登录 + 任务计划(用户登录时启动)

重点提醒(工控踩坑点)

  1. 不要尝试直接把 WinForm 当成 Windows 服务安装,必出问题,这是 Windows Session0 隔离机制,不是程序 bug。
  2. 你的采集程序里所有业务逻辑一定要放到非 UI 线程。如果你的采集逻辑写在 UI 事件(按钮点击)里面,当窗口无法创建时,采集会停止。 你现在手动运行没问题,但是无桌面会话启动时,UI 消息循环存在,但窗口不可见;如果业务依赖 UI 控件,就会失效。
  3. 路径问题:开机启动时工作目录不是 exe 所在目录,你的程序如果读取相对路径配置文件,会找不到文件。 解决:在任务计划 / NSSM 里设置【起始于 (可选)】,填写 exe 所在文件夹,不用修改你的 WinForm 代码。

推荐选型建议(你的 MES / 上位机采集场景)

工控采集,优先:NSSM。 优势:崩溃自动重启、日志、服务状态监控,部署简单,原有 WinForm 完全不动;代价:看不到主窗口,只能看输出日志文件。 如果你日常需要看界面调试,那就用【自动登录 + 任务计划】,上电自动进桌面,程序自动弹出窗口,和你手动点开一模一样。

你可以告诉我两点,我帮你锁定最终方案:

  1. 是否需要看到 WinForm 界面(还是只需要后台采集写日志)?
  2. 工控机是内网单机,还是接入域环境,能不能接受开启 Windows 自动登录?

💥💥💥💥💥💥💥💥

NSSM 部署方案 + BAT 脚本(管理员运行)

前提:不改你原有 WinForm 采集程序。NSSM 把你的 exe 包装成 Windows 服务;服务启动后进程后台跑,没有可视化窗口,采集逻辑、PLC 通信、日志写入正常(前提:采集业务不在 UI 线程里)。 注意:NSSM 64 位 / 32 位要和你的 exe 匹配,下载后把对应 nssm.exe 放到和 bat 同目录。

目录结构示例

D:\Collector\
├─ Collector.exe      // 你的WinForm采集程序
├─ nssm.exe           // 对应系统位数的NSSM
├─ InstallService.bat // 安装服务脚本
├─ UninstallService.bat // 卸载服务脚本

InstallService.bat(安装 + 注册服务,右键以管理员身份运行)

@echo off
setlocal enabledelayedexpansion
cd /d "%~dp0"

:: ===================== CONFIG =====================
set "SERVICE_NAME=CollectorService"
set "SERVICE_DISPLAY_NAME=Data Collector Service"
set "EXE_PATH=%~dp0Collector.exe"
set "WORK_DIR=%~dp0"
:: ===================================================

echo ==============================================
echo Service Name: %SERVICE_NAME%
echo Executable:    %EXE_PATH%
echo Working Dir:   %WORK_DIR%
echo ==============================================
echo.

:: Check admin rights
net session >nul 2>&1
if %errorlevel% neq 0 (
    echo ERROR: This script MUST run as Administrator!
    echo Right click - Run as administrator.
    pause
    exit /b 1
)

if not exist "nssm.exe" (
    echo ERROR: nssm.exe not found in current folder!
    pause
    exit /b 1
)
if not exist "%EXE_PATH%" (
    echo ERROR: Cannot find %EXE_PATH%
    pause
    exit /b 1
)

:: Install service
echo Run: nssm install %SERVICE_NAME% "%EXE_PATH%"
nssm install %SERVICE_NAME% "%EXE_PATH%"
if %errorlevel% neq 0 (
    echo ERROR: nssm install failed, return code=%errorlevel%
    pause
    exit /b %errorlevel%
)

nssm set %SERVICE_NAME% DisplayName %SERVICE_DISPLAY_NAME%
if %errorlevel% neq 0 (
    echo ERROR: Set DisplayName failed, return code=%errorlevel%
    pause
    exit /b %errorlevel%
)

nssm set %SERVICE_NAME% AppDirectory "%WORK_DIR%"
if %errorlevel% neq 0 (
    echo ERROR: Set AppDirectory failed, return code=%errorlevel%
    pause
    exit /b %errorlevel%
)

:: Recovery settings
nssm set %SERVICE_NAME% AppExit Default RESTART
nssm set %SERVICE_NAME% AppRestartDelay 10000

:: Startup auto
nssm set %SERVICE_NAME% Start SERVICE_AUTO_START

:: Redirect logs
nssm set %SERVICE_NAME% AppStdout "%~dp0service_out.log"
nssm set %SERVICE_NAME% AppStderr "%~dp0service_err.log"

echo.
echo Service installed successfully.
echo Check services.msc for "%SERVICE_DISPLAY_NAME%"
echo Start command: nssm start %SERVICE_NAME%
echo.
pause

UninstallService.bat(卸载服务,管理员运行)

@echo off
setlocal enabledelayedexpansion
cd /d "%~dp0"

set "SERVICE_NAME=CollectorService"

net session >nul 2>&1
if %errorlevel% neq 0 (
    echo ERROR: This script MUST run as Administrator!
    pause
    exit /b 1
)

if not exist "nssm.exe" (
    echo ERROR: nssm.exe not found!
    pause
    exit /b 1
)

echo Stopping service %SERVICE_NAME%
nssm stop %SERVICE_NAME%

echo Removing service %SERVICE_NAME%
nssm remove %SERVICE_NAME% confirm

echo Service uninstalled.
pause

手动启动 / 停止命令(管理员 CMD)

nssm start CollectorService
nssm stop CollectorService

重要注意事项(工控踩坑)

  1. NSSM 版本
    • 64 位系统:用win64\nssm.exe;32 位系统用win32\nssm.exe,不要混用。
    • 下载地址:https://nssm.cc/download
    只需要提取 nssm.exe 一个文件即可,不需要其他文档。
  2. Session 0 无桌面 服务启动的 Collector.exe 进程没有窗口。任务管理器可以看到进程,日志文件正常输出;不能弹出 WinForm 界面。
    • 适合:后台采集、PLC 通讯、写文件;
    • 如果采集逻辑依赖 UI 控件 / 窗口句柄,会异常。
  3. 路径不要带中文 / 空格 如果路径有空格,脚本里%EXE_PATH%已经带引号,但是尽量工控路径用纯英文,减少坑。
  4. 权限 默认 NSSM 服务账户是LocalSystem,权限很高,可以访问本地磁盘;访问网络共享文件夹会有坑(LocalSystem 没有网络身份)。 如果需要访问网络盘:额外命令指定账号密码: nssm set CollectorService ObjectName ".\你的账号" "密码"
  5. 测试流程(强烈建议先测试,不要直接上生产工控机)
    1. 先手动双击 Collector.exe,确认采集正常;
    2. 运行 InstallService.bat 注册;
    3. nssm start CollectorService启动;
    4. 看 service_err.log、业务日志,确认采集是否正常;
    5. 测试:任务管理器 kill 掉 Collector.exe,看 10 秒后是否自动重启;
    6. 最后测试重启机器,不登录桌面,看进程是否自动拉起。

可选扩展:如果需要查看 NSSM 图形配置界面

管理员 CMD 执行:

nssm edit CollectorService

弹出 NSSM 可视化配置窗口,可以修改所有参数。

上一篇 C# + Scriban:生成 HTML 报表,自动发邮件(MES / 生产报表场景)
下一篇 DateTime.UtcNow , DateTime.Now 有什么区别
signoz和日志系统 elk的区别?

signoz和日志系统 elk的区别?

SigNoz vs ELK(Elastic Stack),结合你 C# 上位机 + PLC 采集 的场景 一句话概括: ELK:以日志全文检索为核心的日志栈(ES 倒排索引,擅长全文搜报错文本),指标、链路追踪是附加能力,多组件拼凑 SigNoz:OTel 原生一体化可观测平台,

2026-10-20
0 0 0
DateTime.UtcNow , DateTime.Now 有什么区别

DateTime.UtcNow , DateTime.Now 有什么区别

DateTime.UtcNow vs DateTime.Now(C#) 一句话总结 DateTime.UtcNow:获取世界协调时间(UTC,零时区),不受电脑系统时区影响。 DateTime.Now:获取本地时间 = UTC 时间 + 当前操作系统时区偏移。 详

2026-10-16
0 0 0
winform 开机启动

winform 开机启动

c# winform 写的采集程序。平时是登录 windows 桌面,手动点开运行 winform 程序。但是要改成开机启动,不要登录 windows 桌面也能执行 winform 程序。有没有什么办法?不要改造 winform 程序 先说核心结论 WinForm

2026-10-16
0 0 0
C# + Scriban:生成 HTML 报表,自动发邮件(MES / 生产报表场景)

C# + Scriban:生成 HTML 报表,自动发邮件(MES / 生产报表场景)

补充:这套方案在工厂圈子使用情况 MailKit 自动发邮件:大量 MES 在用 Playwright 自动截图 HTML 报表:不少工厂自动化报表在用,属于成熟方案,但不是每个项目都会上。很多项目嫌麻烦就直接 PDF 或者纯表格邮件。 Scriban + Playwright

2026-10-14
0 0 0
C# + Scriban 做静态站点生成

C# + Scriban 做静态站点生成

C# + Scriban 做静态站点生成(对标 baifenwei 的 generate_site.py) Scriban 是 .NET 生态下高性能模板引擎,语法类似 Liquid / Jinja2,刚好用来替代 Python Jinja2,写一个 C# 控制台程序(GenerateSite

2026-10-14
0 0 0
REA(rea.tools)“万物可逆向”:噱头很大,但不是真的什么都能逆向

REA(rea.tools)“万物可逆向”:噱头很大,但不是真的什么都能逆向

REA(rea.tools)“万物可逆向”:噱头很大,但不是真的什么都能逆向 全称 REA = Reverse Engineer Anything,“逆向一切” 只是项目口号,不是能力承诺。 https://rea.tools https://github.com/morluto

2026-10-14
0 0 0
采集上位机LOG文件,不停追加,文件大小50MB

采集上位机LOG文件,不停追加,文件大小50MB

txt 文件很大,40MB,50MB,txt 持续追加,这种场景。Logstash File Input、Flume Taildir、阿里云 Logtail、NewLifeX/X 日志查看工具 Klogg Log Parser Lizard https://githu

2026-10-10
0 0 0
AOI 图片上传 【分布式】方案

AOI 图片上传 【分布式】方案

车间 aoi 的相机图片上传,用飞牛 nas,群晖 nas,高并发,按 5TB / 天、60 天、500 台设备,能不能抗住?如果我在一台服务器放多个 ftp 服务,每条线一个 ftp 服务,端口 8001,第二条线 ftp 服务,端口 8002。ftp 靠谱还 nas 靠谱?稳定,生成环境

2026-10-09
0 0 0
MES 系统 的几种ID比较,雪花id,ULID,UUID

MES 系统 的几种ID比较,雪花id,ULID,UUID

实际场景:浏览器指纹和cookie的UUID 项目FingerprintJS visitorId bdc65ad12633d79792ceeca33a78e6c551.la 访客 ID 5a00c3da-ab80-513d-b7a7-894bcaaecf92来源读取浏览器硬件 / 软件特征,前

2026-10-09
0 0 0
ACCESS数据库访问报错

ACCESS数据库访问报错

AI最擅长找错,分析原因。 💥💥问题1:exclusively locked 因为ACCESS打开数据库后,表:TO_LOGGER_INFO ,当设计视图窗体时,另一个c#小程序去访问这个access数据库会报错: ERROR [HY000] [Microsoft][ODBC Mi

2026-09-29
0 0 0