当前位置: 首页 > news >正文

VC++创建windows服务程序

目录

1.关于windows标准可执行程序和服务程序

2.服务相关整理

2.1 VC++编写服务

2.2 服务注册

2.3  服务卸载

2.4 启动服务

2.5 关闭服务

2.6 sc命令

2.7 查看服务

3.标准程序

3.1 后台方式运行标准程序

3.2 查找进程

3.3 终止进程


       以前经常在Linux下编写服务器程序,服务器程序大多都是以守护进程方式运行,并且很多都是要开机启动方式进行。最近工作需要编写跨平台的服务,所以就 想了解一下windows下服务开发,通过查询资料发现windows服务完全是另外一回事,windows没有linux那种以&方式运行服务器程序的方式,需要单独使用另外一套api来开发。

1.关于windows标准可执行程序和服务程序

Window 标准的exe可执行程序通常有一个用户界面,Console或GUI,通常由用户来启动或停止.
Windows服务是运行在windows后台指定用户下(默认System)的应用程序,它没有标准的UI界面,相比标准的EXE程序,Windows服务是在服务开始的时候创建,而在服务结束的时候销毁,而且可以设置服务是否与操作系统一起启动,一起关闭。
它支持三种方式:1)自动方式 2)手动方式 3)禁用 。
自动方式的时候,windows服务将在OS启动后自动启动运行,而手动方式则必须手工启动服务,禁用的情况下服务将不能被启动。另外标准的EXE默认使用的当前登录的用户,而windows服务则默认使用System用户,这在对系统资源访问的时候特别需要注意。
Windows Service 是主要用于服务器环境而长期运行的应用程序, 这类程序不需要有用户界面或者任何模拟输出。 任何的用户消息通常都是记录在Windows 事件日志里。Windows Service可以在操作系统启动的时候开始,一直在后台运行,当有需要时也可以手动启动,我们可以通过管理工具里面的服务进行统一管理。当系统启动完毕后,Windows服务并不需要通过登陆页面后才能启动,而我们启动一般的exe文件却要先登陆Windows后才能启动它。
Windows Service 是一种可随 Windows 操作系统启动而启动的,在后台运行的,通常不和用户产生交互的程序。它无法通过双击来运行,类似于 Unix 守护进程(daemon processes),当用户注销时它也不会停止。
Windows 服务由三部分组成:1.一个服务可执行文件;2.一个服务控制程序(SCP);3.服务控制管理器(SCM),
负责在 HKLM\SYSTEM\CurrentControlSet\Services 下创建服务键值。用户可通过 SCP 控制服务的启动、停止、暂停等,SCP 会通过 SCM 调用服务程序。服务程序、服务控制程序(SCP,service control program)和服务控制管理器(SCM,service control manager)组成了Windows服务。我们可以通过服务控制程序操纵服务控制管理器来配置、启动、暂停、停止服务程序。其中服务程序和服务控制程序可以由我们自己来编写扩展,而服务控制管理器(\windows\system32\servics.exe)则是操作系统内置的一个部件。         

重点说明:
Windows服务程序其实并不神秘,它只是遵循特定规则编写的一个程序。只要遵循这个特定的规则与服务控制管理器正确的交互,就可实现我们的服务程序。而我们只要能实现一个简单的服务程序,设计一个能处理复杂业务的服务也并非难事,因为从结构上看两者并没有太大的区别。
只要遵循与SCM交互的规则,设计服务程序与设计普通的应用程序几乎没什么区别。

2.服务相关整理

2.1 VC++编写服务

// MyService.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <Windows.h>
#include <iostream>using namespace std;/*
BOOL IsInstalled(); 
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);TCHAR szServiceName[] = _T("MyService");
BOOL bInstall;
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
DWORD dwThreadID;
SC_HANDLE hSCM;
SC_HANDLE hService;
*//*
OpenSCManager 用于打开服务控制管理器;
CreateService 用于创建服务;
OpenService用于打开已有的服务,返回该服务的句柄;
ControlService则用于控制已打开的服务状态,这里是让服务停止后才删除;
DeleteService 用于删除指定服务。RegisterServiceCtrlHandler 注册服务控制
*///定义全局函数变量  
void Init();
BOOL IsInstalled();
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);TCHAR szServiceName[] = _T("MyService");
BOOL bInstall;
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
DWORD dwThreadID;int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR    lpCmdLine,int       nCmdShow)
{Init();dwThreadID = ::GetCurrentThreadId();SERVICE_TABLE_ENTRY st[] ={{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },{ NULL, NULL }};if (_stricmp(lpCmdLine, "/install") == 0){Install();}else if (_stricmp((LPCTSTR)lpCmdLine, "/uninstall") == 0){Uninstall();}else{if (!::StartServiceCtrlDispatcher(st)){LogEvent(_T("Register Service Main Function Error!"));}}return 0;
}//初始化
void Init()
{hServiceStatus = NULL;status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;status.dwCurrentState = SERVICE_START_PENDING;status.dwControlsAccepted = SERVICE_ACCEPT_STOP;status.dwWin32ExitCode = 0;status.dwServiceSpecificExitCode = 0;status.dwCheckPoint = 0;status.dwWaitHint = 0;
}//服务主函数,这在里进行控制对服务控制的注册
void WINAPI ServiceMain()
{status.dwCurrentState = SERVICE_START_PENDING;status.dwControlsAccepted = SERVICE_ACCEPT_STOP;//注册服务控制  hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);if (hServiceStatus == NULL){LogEvent(_T("Handler not installed"));return;}SetServiceStatus(hServiceStatus, &status);status.dwWin32ExitCode = S_OK;status.dwCheckPoint = 0;status.dwWaitHint = 0;status.dwCurrentState = SERVICE_RUNNING;SetServiceStatus(hServiceStatus, &status);//模拟服务的运行。应用时将主要任务放于此即可  //可在此写上服务需要执行的代码,一般为死循环  while (1){FILE *p;p = fopen("c:\\log.txt", "ab+");SYSTEMTIME st;GetSystemTime(&st);char time[100] = { 0 };_sntprintf(time, 100, "%4d-%02d-%02d %02d:%02d:%02d\r\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);fwrite(time, strlen(time), 1, p);fclose(p);Sleep(1000);}status.dwCurrentState = SERVICE_STOPPED;SetServiceStatus(hServiceStatus, &status);
}//Description:          服务控制主函数,这里实现对服务的控制,  
//                      当在服务管理器上停止或其它操作时,将会运行此处代码  
void WINAPI ServiceStrl(DWORD dwOpcode)
{switch (dwOpcode){case SERVICE_CONTROL_STOP:status.dwCheckPoint = 1;status.dwCurrentState = SERVICE_STOP_PENDING;SetServiceStatus(hServiceStatus, &status);Sleep(500);status.dwCheckPoint = 0;status.dwCurrentState = SERVICE_STOPPED;SetServiceStatus(hServiceStatus, &status);PostThreadMessage(dwThreadID, WM_CLOSE, 0, 0);break;case SERVICE_CONTROL_PAUSE:break;case SERVICE_CONTROL_CONTINUE:break;case SERVICE_CONTROL_INTERROGATE:break;case SERVICE_CONTROL_SHUTDOWN:exit(0);break;default:LogEvent(_T("Bad service request"));}
}//判断服务是否已经被安装
BOOL IsInstalled()
{BOOL bResult = FALSE;//打开服务控制管理器  SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM != NULL){//打开服务  SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_QUERY_CONFIG);if (hService != NULL){bResult = TRUE;::CloseServiceHandle(hService);}::CloseServiceHandle(hSCM);}return bResult;
}//安装服务函数
BOOL Install()
{//检测是否安装过if (IsInstalled())return TRUE;//打开服务控制管理器  SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM == NULL){MessageBox(NULL, _T("Couldn't open service manager"), szServiceName, MB_OK);return FALSE;}//获取程序目录TCHAR szFilePath[MAX_PATH];::GetModuleFileName(NULL, szFilePath, MAX_PATH);//创建服务  SC_HANDLE hService = ::CreateService(hSCM, szServiceName, szServiceName,SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,szFilePath, NULL, NULL, _T(""), NULL, NULL);//检测创建是否成功if (hService == NULL){::CloseServiceHandle(hSCM);MessageBox(NULL, _T("Couldn't create service"), szServiceName, MB_OK);return FALSE;}//释放资源::CloseServiceHandle(hService);::CloseServiceHandle(hSCM);return TRUE;
}//删除服务函数
BOOL Uninstall()
{//检测是否安装过if (!IsInstalled())return TRUE;//打开服务控制管理器SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);if (hSCM == NULL){MessageBox(NULL, _T("Couldn't open service manager"), szServiceName, MB_OK);return FALSE;}//打开具体服务SC_HANDLE hService = ::OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);if (hService == NULL){::CloseServiceHandle(hSCM);MessageBox(NULL, _T("Couldn't open service"), szServiceName, MB_OK);return FALSE;}//先停止服务SERVICE_STATUS status;::ControlService(hService, SERVICE_CONTROL_STOP, &status);//删除服务  BOOL bDelete = ::DeleteService(hService);::CloseServiceHandle(hService);::CloseServiceHandle(hSCM);if (bDelete)  return TRUE;LogEvent(_T("Service could not be deleted"));return FALSE;
}//记录服务事件
void LogEvent(LPCTSTR pFormat, ...)
{TCHAR    chMsg[256];HANDLE  hEventSource;LPTSTR  lpszStrings[1];va_list pArg;va_start(pArg, pFormat);_vstprintf(chMsg, pFormat, pArg);va_end(pArg);lpszStrings[0] = chMsg;hEventSource = RegisterEventSource(NULL, szServiceName);if (hEventSource != NULL){ReportEvent(hEventSource, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (LPCTSTR*)&lpszStrings[0], NULL);DeregisterEventSource(hEventSource);}
}

编译产物如下:

服务程序本身也是PE格式的文件。

2.2 服务注册

MyService.exe /install

2.3  服务卸载

MyService.exe /uninstall

可以看到服务已经被删除

2.4 启动服务

net start MyService

2.5 关闭服务

net stop MyService

2.6 sc命令

sc命令可以用于管理系统服务、计划任务、系统日志等方面,是不可或缺的神器。

(1) 要查看系统服务列表
sc query state=all

(2) 启动或者停止服务
sc start 服务名
sc stop 服务名

(3) 查看服务属性
例如:以CSV格式输出服务的属性
sc query 服务名 /format:csv

(4) 创建服务
sc create HelloWorldService binPath= "D:\VC\vcDemo\Debug\helloworld.exe"

(5) 山存储服务 
sc delete HelloWorldService

实战演示

创建服务

sc create MyService binPath= "D:\VC\vcDemo\Debug\MyService.exe"

启动服务

sc start MyService

关闭服务

sc stop MyService

删除服务

sc delete MyService

2.7 查看服务

方法一

services.msc

方法二:

电脑 - 右键管理

3.标准程序

3.1 后台方式运行标准程序

@ECHO OFF
%1 start mshta vbscript:createobject("wscript.shell").run("""%~0"" ::",0)(window.close)&&exit
start /b helloworld.exe

3.2 查找进程

tasklist | findstr hello

3.3 终止进程

@ECHO OFF
taskkill /im helloworld.exe /f
 

微软官方关于服务主函数说明:

编写服务程序主函数 - Win32 apps | Microsoft Learn

关于Windows服务,发现一个写的比较好的博客:

 C++之创建Windows系统服务_c++编写windows服务-CSDN博客

相关文章:

VC++创建windows服务程序

目录 1.关于windows标准可执行程序和服务程序 2.服务相关整理 2.1 VC编写服务 2.2 服务注册 2.3 服务卸载 2.4 启动服务 2.5 关闭服务 2.6 sc命令 2.7 查看服务 3.标准程序 3.1 后台方式运行标准程序 3.2 查找进程 3.3 终止进程 以前经常在Linux下编写服务器程序…...

连续爆轰发动机

0.什么是爆轰 其反应区前沿为一激波。反应区连同前驱激波称为爆轰波。爆轰波扫过后&#xff0c;反应区介质成为高温高压的爆轰产物。能够发生爆轰的系统可以是气相、液相、固相或气-液、气-固和液-固等混合相组成的系统。通常把液、固相的爆轰系统称为炸药。 19世纪80年代初&a…...

交通物流模型 | 基于时空注意力融合网络的城市轨道交通假期短时客流预测

短时轨道交通客流预测对于交通运营管理非常重要。新兴的深度学习模型有效提高了预测精度。然而,大部分现有模型主要针对常规工作日或周末客流进行预测。由于假期客流的突发性和无规律性,仅有一小部分研究专注于假期客流预测。为此,本文提出一个全新的时空注意力融合网络(ST…...

2.2.1 嵌入式工程师必备软件

1 文件比较工具 在开发过程中,不论是对代码的对比,还是对log的对比,都是必不可不少的,通过对比,我们可以迅速找到差异,定位问题。当前常用的对比工具有:WinMerge,Diffuse,Beyond Compare,Altova DiffDog,AptDiff,Code Compare等。这里推荐使用Beyond Compare,它不…...

深入了解 RabbitMQ:高性能消息中间件

目录 引言&#xff1a;一、RabbitMQ 介绍二、核心概念三、工作原理四、应用场景五、案例实战 引言&#xff1a; 在现代分布式系统中&#xff0c;消息队列成为了实现系统间异步通信、削峰填谷以及解耦组件的重要工具。而RabbitMQ作为一个高效可靠的消息队列解决方案&#xff0c;…...

【数据库——MySQL】(14)过程式对象程序设计——游标、触发器

目录 1. 游标1.1 声明游标1.2 打开游标1.3 读取游标1.4 关闭游标1.5 游标示例 2. 触发器2.1 创建触发器2.2 修改触发器2.3 删除触发器2.4 触发器类型2.5 触发器示例 参考书籍 1. 游标 游标一般和存储过程一起配合使用。 1.1 声明游标 要使用游标&#xff0c;需要用到 DECLAR…...

位移贴图和法线贴图的区别

位移贴图和法线贴图都是用于增强模型表面细节和真实感的纹理贴图技术&#xff0c;但是它们之间也存在着差异。 1、什么是位移贴图 位移贴图&#xff1a;位移贴图通过在模型顶点上定义位移值来改变模型表面的形状。该贴图包含了每个像素的高度值信息&#xff0c;使得模型的细节…...

【typescript】面向对象(下篇),包含接口,属性的封装,泛型

假期第八篇&#xff0c;对于基础的知识点&#xff0c;我感觉自己还是很薄弱的。 趁着假期&#xff0c;再去复习一遍 面向对象&#xff1a;程序中所有的操作都需要通过对象来完成 计算机程序的本质就是对现实事物的抽象&#xff0c;抽象的反义词是具体。比如照片是对一个具体的…...

基于SpringBoot的视频网站系统

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 视频分享管理 视频排名管理 交流论坛管理 留言板管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 使用旧方法对视频信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运…...

23.3 Bootstrap 框架4

1. 轮播 1.1 轮播样式 在Bootstrap 5中, 创建轮播(Carousel)的相关类名及其介绍: * 1. carousel: 轮播容器的类名, 用于标识一个轮播组件. * 2. slide: 切换图片的过渡和动画效果. * 3. carousel-inner: 轮播项容器的类名, 用于包含轮播项(轮播图底下椭圆点, 轮播的过程可以显…...

ESP32设备驱动-I2C-LCD1602显示屏驱动

I2C-LCD1602显示屏驱动 1、LCD1602介绍 LCD1602液晶显示器是广泛使用的一种字符型液晶显示模块。它是由字符型液晶显示屏(LCD)、控制驱动主电路HD44780及其扩展驱动电路HD44100,以及少量电阻、电容元件和结构件等装配在PCB板上而组成。 通过前面的实例我们知道,并口方式…...

vs工具箱在哪里找

VS工具箱在标题栏 视图->工具箱...

uniapp 事件委托失败 获取不到dataset

问题&#xff1a; v-for 多个span ,绑定点击事件 代码:view里包着一个span, <view class"status-list" tap"search"><span class"status-item" v-for"(key,index) in statusList" :key"index" :data-key"k…...

windows系统下pycharm配置anaconda

参考&#xff1a;超详细的PycharmAnconda安装配置教程_pycharm conda_罅隙的博客-CSDN博客 下载好anaconda安装后&#xff0c;比如我们安装在D盘anaconda文件夹下&#xff0c;在pycharm配置好环境激活时出现问题&#xff0c;可能是电脑没有配置环境变量 需要将一下4行添加到电…...

2023年CSP-J真题详解+分析数据

目录 亲身体验 江苏卷 选择题 阅读程序题 阅读程序(1&#xff09; 判断题 单选题 阅读程序(2) 判断题 单选题 阅读程序(3) 判断题 单选题 完善程序题 完善程序(1) 完善程序(2) 2023CSP-J江苏卷详解 小结 亲身体验 2023年的CSP-J是在9月16日9:30--11:30进行…...

10.3 调试事件转存进程内存

我们继续延申调试事件的话题&#xff0c;实现进程转存功能&#xff0c;进程转储功能是指通过调试API使获得了目标进程控制权的进程&#xff0c;将目标进程的内存中的数据完整地转存到本地磁盘上&#xff0c;对于加壳软件&#xff0c;通常会通过加密、压缩等手段来保护其代码和数…...

深度学习实战基础案例——卷积神经网络(CNN)基于MobileNetV3的肺炎识别|第3例

文章目录 前言一、数据集介绍二、前期工作三、数据集读取四、构建CA注意力模块五、构建模型六、开始训练 前言 Google公司继MobileNetV2之后&#xff0c;在2019年发表了它的改进版本MobileNetV3。而MobileNetV3共有两个版本&#xff0c;分别是MobileNetV3-Large和MobileNetV2-…...

机器学习 面试/笔试题(更新中)

1. 生成模型 VS 判别模型 生成模型&#xff1a; 由数据学得联合概率分布函数 P ( X , Y ) P(X,Y) P(X,Y),求出条件概率分布 P ( Y ∣ X ) P(Y|X) P(Y∣X)的预测模型。 朴素贝叶斯、隐马尔可夫模型、高斯混合模型、文档主题生成模型&#xff08;LDA&#xff09;、限制玻尔兹曼机…...

【算法题】100019. 将数组分割成最多数目的子数组

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 题目&#xff1a; 给你一个只包含 非负 整数的数组 n…...

commons-io工具类常用方法

commons-io是Apache Commons项目的一个模块&#xff0c;提供了一系列处理I/O&#xff08;输入/输出&#xff09;操作的工具类和方法。它旨在简化Java I/O编程&#xff0c;并提供更多的功能和便利性。 读取文件内容为字符串 String path"C:\\Users\\zhang\\Desktop\\myyii\…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

Python训练营-Day26-函数专题1:函数定义与参数

题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一个名为 calculate_circle_area 的函数&#xff0c;该函数接收圆的半径 radius 作为参数&#xff0c;并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求&#xff1a;函数接收一个位置参数 radi…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

PLC入门【4】基本指令2(SET RST)

04 基本指令2 PLC编程第四课基本指令(2) 1、运用上接课所学的基本指令完成个简单的实例编程。 2、学习SET--置位指令 3、RST--复位指令 打开软件(FX-TRN-BEG-C)&#xff0c;从 文件 - 主画面&#xff0c;“B: 让我们学习基本的”- “B-3.控制优先程序”。 点击“梯形图编辑”…...