李進豪
(廣東生態(tài)工程職業(yè)學院信息工程學院,廣州 510520)
充分發(fā)揮新一代信息技術的優(yōu)勢,推進智能技術與教育教學的深度融合,推動教學模式變革和課堂體系重構,不斷提升教育教學質量,助力教育實現跨越式發(fā)展,是教育教學改革的主旋律。調研表明,在教育信息化的推進過程中,對于未成年學生的電腦管理,除了正面的教育引導外,有效的遠程監(jiān)管是必要的。以小學生的電腦管理為例,兒童電腦管理軟件一方面有利于提升學生的學習自覺性,另一方面也有利于基于過程分析提升學生的學習有效性,助力提升線上教與學的質量。
作為廣東省職業(yè)教育 “雙師型” 名教師工作室主持人(信息技術方向),有助推我省智能技術與教育教學深度融合的職責。在助推基礎教育教學信息化的過程中,我們發(fā)現不少家長對小學生使用電腦都存在 “憂慮”,主要包括:訪問不良網站、運行不良程序、學習效率偏低等。因此,基于兒童電腦管理軟件減輕家長的憂慮是一項非常有意義的研究工作。
作為廣東省教育科學規(guī)劃課題、廣東省職業(yè)院校文化素質教育研究課題負責人(T 型信息技術工匠人才培養(yǎng)),致力于 “基于完成品的項目教學模式” 研究與實踐,旨在培育 “就業(yè)有核心競爭力、創(chuàng)業(yè)有創(chuàng)新能力、升學有可持續(xù)發(fā)展能力” 的T 型工匠人才。實踐證明,在課堂教學與畢業(yè)設計過程中,基于真實項目開展人才培養(yǎng),更有利于培養(yǎng)T 型工匠人才,更有利于助力學生成為受人尊重的專業(yè)技術人才。因此,作為基礎教育教學信息化推進過程中的配套附件 “兒童電腦管理軟件”,課題組主持開發(fā)并引入實際教學工作中是一項非常有價值的教科研工作。
根據調研與分析,結合基礎教育公益性管理軟件的需求,以實用夠用為原則,以有利于兒童成長為準繩,兒童電腦管理軟件的主要功能包括:溫馨提示、進程管理、實時監(jiān)管等。
2.1.1 溫馨提示
主要用于向兒童端發(fā)送溫馨提示,該提示在指定時間內自動關閉。目的是加強家長與兒童的溝通,協(xié)助兒童進行有效學習。
2.1.2 進程管理
主要包括:啟動單個進程、啟動批量進程、關閉單個進程、關閉批量進程等。目的是消除不必要的學習干擾,助力兒童提升學習有效性。
2.1.3 實時監(jiān)管
主要包括:兒童電腦進程監(jiān)管、兒童電腦實時截圖查看、兒童電腦動態(tài)截圖瀏覽(在指定時間間隔自動截圖)等。目的是基于過程分析協(xié)助兒童解決學習過程中的困難,提升學習效率與學習成就感。
2.2.1 基于Winsock的信息收發(fā)
Winsock 是Windows 下的網絡編程規(guī)范,最常用的模式是 “服務器+客戶機” 模型。在這種模型中,服務器在一個IP 地址監(jiān)聽服務請求,當客戶機對服務器提出連接請求時,則回應客戶機的請求,進而建立網絡通信的連接。在網絡通信中,最基本的信息包括:本地IP地址+端口號、對方IP地址+端口號、通訊信息等。
2.2.2 兒童端
自動獲取本機IP地址,作為 “服務器+客戶機” 模型中的 “服務器”。兒童電腦開機時,兒童端自動偵聽家長端(客戶機)的連接請求,連接成功后,則根據家長端的指令自動完成相關的工作任務。
2.2.3 家長端
自動獲取本機IP 地址和兒童端IP 地址,作為 “服務器+客戶機” 模型中的 “客戶機”。家長電腦開機后,家長根據需要啟動與兒童電腦的 “連接”(或 “斷開”)。如果選擇連接,在連接成功后,家長端可以發(fā)出相應的指令(溫馨提示、進程管理、實時監(jiān)管等),進而實現對兒童電腦的管理(旨在提升學習有效性)。
2.2.4 開發(fā)平臺
Microsoft Visual Studio 2022(WPF+C#)。
2.2.5 安全策略
兒童端在兒童電腦開機時自動執(zhí)行并隱藏界面(減少干擾),等待家長端的指令。家長端根據需要選擇性地與兒童端建立網絡通信,但連接時需要使用登錄賬號和密碼(賬號和密碼均使用加密方式保存),以確保安全性。在滿足實際需求的前提下,為了減少存儲空間和提高電腦的工作效率,實時監(jiān)管與動態(tài)監(jiān)管均采用“截圖方式” 進行。其中,在保證圖片具有一定清晰度的前提下,所有圖片均采用壓縮方式進行傳輸和保存。
兒童電腦管理軟件基本原理如圖1所示。
圖1 兒童電腦管理軟件基本原理
foreach(IPAddress MyIPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if(MyIPAddress.AddressFamily.ToString()==“InterNetwork”)
{
localIP = MyIPAddress.ToString();
break;
}
}
string filePath = @“myipstart.txt”;
string mys = File.ReadAllText(filePath);
string mycommand="notepad.exe";
System.Diagnostics.Process.Start(mycommand);
Process[]myp;
myp = Process.GetProcesses();
string mycommand =“notepad”;
Process[]myp;
myp = Process.GetProcesses();
foreach(Process p in myp)
{
if(p.ProcessName.ToUpper().Trim()== mycom?mand.ToUpper().Trim())p.Kill();
}
(1)調用窗體
myMessageshow = mycommand;
ShowMessage myw=new ShowMessage();
myw.Show();
(2)窗體延時自動關閉
DispatcherTimer collectTimer = new DispatcherTimer();
collectTimer.Interval = new TimeSpan(0,0,0,0,5000);
collectTimer.IsEnabled = true;
collectTimer.Tick += Timer_Tick;
private void Timer_Tick(object sender,EventArgs e)
{
this.Close();
}
System.Drawing.Rectangle myrc = SystemInformation.VirtualScreen;
var bitmap = new Bitmap(myrc.Width,myrc.Height,System.Drawing.Imaging.PixelFormat.Format32 bppArgb);
using(Graphics memoryGrahics = Graphics.FromImage(bitmap))
{
memoryGrahics.CopyFromScreen(myrc.X,myrc.Y,0,0,myrc.Size,CopyPixelOperation.SourceCopy);
}
MemoryStream myms = null;
myms = new MemoryStream();
bitmap.Save(myms,System.Drawing.Imaging.Image Format.Png);
var eps = new EncoderParameters(2);
eps.Param[0]= new EncoderParameter(System.Drawing.Imaging.Encoder.Quality,5L);
eps.Param[1]= new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth,24L);
ImageCodecInfo[]encoders = ImageCodecInfo.GetIma?geEncoders();
ImageCodecInfo mycodecInfo= encoders[1];
for(int j = 0;j < encoders.Length;++j)
{
if(encoders[j].MimeType==“image/jpeg”)
{
mycodecInfo = encoders[j];break;
}
}
bitmap.Save(myms,mycodecInfo,eps);
MemoryStream fs = new MemoryStream();
int length =buff.Length;
string tstr= Encoding.Default.GetString(buff);
if(tstr.Length > 0)
{
fs.Write(buff,0,length);
fs.Flush();
Bitmap img = new Bitmap(fs);
DateTime dt = DateTime.Now;
string filePath = @“jpg”+dt.Minute.ToString()+dt.Second.ToString()+“.jpg”;
img.Save(@filePath,ImageFormat.Jpeg);
fs.Close();
}
IPEndPoint myipe = new IPEndPoint(IPAddress.Parse(MytxtService.Text), 8081);
mytcp = new TcpListener(myipe);
mytcp.Start();
mytcp.BeginAcceptSocket(new AsyncCallback(Accept SocketCB), mytcp);
Socket mysoc = new Socket(AddressFamily.Inter?Network, SocketType.Stream, ProtocolType.Tcp);
mysoc.Connect(IPAddress.Parse(MytxtService.Text),8081);
mysoc.BeginReceive(buff, 0, buff.Length, SocketFlags.
None, new AsyncCallback(ReceiveCB), mysoc);
foreach(string mycommandstr in myarr)
{
string mysc =“”;
mysc = mycommandstr +“.exe”;try
{
System.Diagnostics.Process.Start(mysc);
}
catch
{
byte[]buffstr= Encoding.Default.GetBytes(mysc +“執(zhí)行失??!”);
mysoc.Send(buffstr);
}
}
4.1.1 兒童端界面
兒童端界面如圖2所示。
圖2 兒童端界面
4.1.2 家長端界面
家長端界面如圖3所示。
圖3 家長端界面
4.2.1 兒童端
兒童電腦開機時,自動運行 “兒童端” 軟件并隱藏界面。在自動獲取本機IP 地址后開始偵聽家長端(客戶機)的連接請求。主要功能包括:
(1)接收來自家長端的溫馨提示,其指令關鍵字為 “L100”。該 “溫馨提示” 窗口,如果兒童端沒有手動關閉,則在5 秒后自動關閉(可自定義,默認為5秒)。
(2)接收來自家長端的進程管理指令,完成進程的啟動或關閉。啟動單個進程的指令關鍵字為“Q100”, 啟動批量進程的指令關鍵字為“Q200”,關閉單個進程的指令關鍵字為“K100”,關閉批量進程的指令關鍵字為 “K200”。其中,如果接受的是批量進程,那么接收的字符串是由用 “,” 作為分隔符的系列進程名稱連接而成的。
(3)接收來自家長端的實時監(jiān)管指令,完成進程名稱的回傳或實時截圖的回傳。其中,回傳兒童電腦進程名稱的指令關鍵字為 “G100”,回傳兒童電腦實時截圖的指令關鍵字為“T100”。
(4)接收來自家長端的關閉指令,指令關鍵字為 “E100”。接受該指令后,自動結束 “兒童端” 軟件的運行。
4.2.2 家長端
家長電腦開機后,家長根據需要啟動連接或關閉與兒童電腦的網絡通信。主要功能包括:
(1)向兒童端發(fā)送溫馨提示時,系統(tǒng)將自動在 “溫馨提示” 前面添加指令關鍵字 “L100”。
(2)向兒童端發(fā)送進程管理指令時,如果選擇的是單個進程,那么進程名稱需要家長手動輸入后發(fā)送,系統(tǒng)將自動在 “單個進程” 前面添加指令關鍵字 “Q100”(啟動進程)或 “K100”(關閉進程);如果選擇批量進程,那么存放進程名稱的文本文件則需要家長提前編輯并保存,啟動進程的文本文件名稱為“txtmystart.txt”(指令關鍵字為 “Q200”),關閉進程的文本文件名稱為“txtmykill.txt”(指令關鍵字為“K200”)。其中,文本文件中的進程名稱用 “,” 進行分隔。
(3)向兒童端發(fā)送實時監(jiān)管指令時,如果發(fā)送的是進程名稱的回傳,那么家長端發(fā)出指令“G100” 后,開始接收來自兒童電腦的進程名稱。在接收兒童電腦進程名稱后,軟件將自動把兒童端與家長端相同的進程名稱刪除,只顯示屬于兒童端電腦專有的進程名稱,以便家長更加高效地實時分析兒童電腦的軟件運行情況。如果發(fā)送的是兒童電腦實時截圖的回傳,那么家長端發(fā)出指令 “T100” 后,開始接收來自兒童電腦的圖片信息,并以 “年+月+日+時+分+秒” 作為JPG 文件的文件名進行保存(同時記錄圖片的保存時間)。如果發(fā)送的是兒童電腦動態(tài)截圖的回傳,那么家長端在發(fā)出指令 “T100”后,將同時啟動計時器,每隔10 秒發(fā)出一條“T100” 的指令(可自定義,默認為10 秒),直到家長端選擇停止兒童電腦動態(tài)截圖的回傳,其接收兒童電腦圖片信息的原理與實時截圖相同,并以壓縮形式的系列JPG文件方式保存。
(4)向兒童端發(fā)送關閉指令時,家長端在發(fā)出指令 “E100” 后,軟件將自動停止與兒童端電腦的連接。
4.3.1 服務器偵聽(兒童端)[1]
string localIP = string.Empty;
foreach(IPAddress MyIPAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
if(MyIPAddress.AddressFamily.ToString()==“InterNetwork”)
{
localIP = MyIPAddress.ToString();
break;
}
}
MytxtService.Text = localIP;
IPEndPoint myipe = new IPEndPoint(IPAddress.Parse(MytxtService.Text),8081);
mytcp = new TcpListener(myipe);
mytcp.Start();
mytcp.BeginAcceptSocket(new AsyncCallback(Accept?SocketCB),mytcp);
MyisClosing = false;
MyShowMsg(“開始偵聽:”+ myipe.Address.ToString()+“:”+ myipe.Port.ToString());
this.Hide();
4.3.2 根據局域網IP地址段自動搜索兒童端IP地址并主動連接[2]
string filePath = @“txtmyipstart.txt”;
string mys = File.ReadAllText(filePath);//局域網的開始IP地址
int myi1=int.Parse(mys.Trim());
filePath = @“txtmyipend.txt”;
mys = File.ReadAllText(filePath);//局域網的結束IP地址
int myi2 = int.Parse(mys.Trim());
string myiptest1=localIP.Substring(0,localIP.Last?IndexOf(‘.’)+1);
string myiptest2 = “”;
for(int i = myi1; i <=myi2; i++)
{
myiptest2 = myiptest1 + i.ToString();
try
{
mysoc.Connect(IPAddress.Parse(myiptest2),8081);
mysoc.BeginReceive(buff,0,buff.Length,Socket?Flags.None,new AsyncCallback(ReceiveCB),mysoc);
MyShowMsg(“連接成功!”);
btnConnect.Content =“斷開”;
this.txtService.Text = myiptest2;
break;
}
catch
{
MyShowMsg(myiptest2+“:連接失??!”);
}
}
4.3.3 指令發(fā)送(家長端)
if(this.btnSend.Content.ToString()==“停止截圖”)
{
this.btnSend.Content =“發(fā)送”;
mytime.Stop();
this.mycom.Text =“溫馨提示”;
return;
}
string sendData_str = txtMsg.Text.Trim();
string mycom=this.mycom.Text.Trim();
if(mycom ==“溫馨提示”)
{
sendData_str =“L100”+ sendData_str;
}
if(mycom ==“啟動單個進程”)
{
sendData_str =“Q100”+ sendData_str;
}
if(mycom ==“啟動批量進程”)
{
string filePath = @“txtmystart.txt”;
string mys = File.ReadAllText(filePath);
sendData_str =“Q200”+ mys;
}
if(mycom ==“關閉單個進程”)
{
sendData_str=“K100”+sendData_str;
}
if(mycom ==“關閉批量進程”)
{
string filePath = @“txtmykill.txt”;
string mys = File.ReadAllText(filePath);
sendData_str =“K200”+mys;
}
if(mycom ==“兒童電腦進程”)
sendData_str =“G100”;
if(mycom ==“兒童電腦實時截圖”)
sendData_str =“T100”;
if(mycom ==“兒童電腦動態(tài)截圖”)
{
sendData_str =“T100”;
this.btnSend.Content =“停止截圖”;
mytime.Start();
}
if(mycom ==“結束偵聽”)sendData_str =“E100”;
MyShowMsg(“發(fā)送命令:”+ sendData_str);
if(sendData_str.Length >= 4)
{
if(sendData_str.Substring(0,4)==“G100”)
{
MyMsg.Items.Add(“兒童端電腦的特別進程如下:”);
}
}
byte[]sendbyte = Encoding.Default.GetBytes(send?Data_str);
mysoc.Send(sendbyte);
時間:2022—2023年第一學期。
班級(課程):廣州市海珠區(qū)某小學四年1班(數學)。
應用截圖(局部),如圖4所示。
圖4 管理應用
時間:2022—2023年第一學期。
班級(課程):廣東生態(tài)工程職業(yè)學院物聯(lián)網2101班(C#物聯(lián)網應用開發(fā))。
應用截圖(局部),如圖5所示。
圖5 人才培養(yǎng)
WPF 提供了統(tǒng)一的編程模型、語言和框架,提供了豐富的.NET UI框架,集成了矢量圖,適用于智慧教育環(huán)境下各種實用程序的開發(fā)。文中提及的代碼全部在Microsoft Visual Studio 2022+Window 10+WPF+C#環(huán)境下調試通過,并應用實際工作中,效果較好。