📄 wceloaderdlg.cpp
字号:
// WCELoaderDlg.cpp : implementation file
//
#include "stdafx.h"
#include "WCELoader.h"
#include "WCELoaderDlg.h"
#include "Tlhelp32.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CWCELoaderDlg dialog
CWCELoaderDlg::CWCELoaderDlg(CWnd* pParent /*=NULL*/)
: CDialog(CWCELoaderDlg::IDD, pParent)
, WCEReadMWD("\\FlashDisk\\NGN\\WCEReadMWD.exe")
, TempFileCOM("\\FlashDisk\\NGN\\WCEReadMWD_COM.exe")
, USBFile("\\硬盘\\WCEReadMWD.exe")
, CFFile("\\存储卡\\WCEReadMWD.exe")
, Comx("COM1:")
{
//{{AFX_DATA_INIT(CWCELoaderDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CWCELoaderDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CWCELoaderDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CWCELoaderDlg, CDialog)
//{{AFX_MSG_MAP(CWCELoaderDlg)
ON_WM_TIMER()
ON_WM_CANCELMODE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CWCELoaderDlg message handlers
BOOL CWCELoaderDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
CRect r;
GetDlgItem(IDC_STATIC_BACK)->GetClientRect(&r);
MoveWindow(&r);
CenterWindow(GetDesktopWindow()); // center to the hpc screen
#ifdef _DEBUG
SetTimer(1, 3000, NULL); // WinCE不能使用0号
#else
SetTimer(2, 1000, NULL); // WinCE不能使用0号
#endif
return TRUE; // return TRUE unless you set the focus to a control
}
BOOL CWCELoaderDlg::Update()
{
// 检测U盘文件版本
if (GetFileVersion(USBFile) > GetFileVersion(WCEReadMWD))
{
UpdateFile(WCEReadMWD, USBFile);
return TRUE;
}
else
{
// 检测CF卡文件版本
if (GetFileVersion(CFFile) > GetFileVersion(WCEReadMWD))
{
UpdateFile(WCEReadMWD, CFFile);
return TRUE;
}
else
{
// 检测COM1更新信号
if (UpdateFromCOM(TempFileCOM))
{
UpdateFile(WCEReadMWD, TempFileCOM);
DeleteFile(TempFileCOM); // 删除临时文件
return TRUE;
}
}
}
return FALSE;
}
BOOL CWCELoaderDlg::UpdateFile(CString FileName, CString srcFile)
{
// 如果正在运行,则结束进程
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 uProcess;
uProcess.dwSize = sizeof(uProcess);
BOOL b = Process32First(hSnapShot, &uProcess);
while (b)
{
if (wcsstr(FileName,uProcess.szExeFile)) // TODO:这个方法不是太好,szExeFile不保险。但由于一般不会误杀进程(除非同名),故先用着。
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,uProcess.th32ProcessID);
TerminateProcess(hProcess, 0);
}
b = Process32Next(hSnapShot, &uProcess);
}
Sleep(1000); // 结束进程后,等待1秒钟,给系统时间清理垃圾。
SetFileAttributes(FileName, GetFileAttributes(FileName) & ~FILE_ATTRIBUTE_READONLY); // 去掉只读属性
// 覆盖文件
if (!CopyFile(srcFile, FileName, FALSE))
{
return FALSE;
}
return TRUE;
}
BOOL CWCELoaderDlg::UpdateFromCOM(CString file)
{
HANDLE hCom;
hCom = CreateFile(Comx, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hCom == INVALID_HANDLE_VALUE)
return FALSE;
DCB dcb;
GetCommState(hCom, &dcb);
dcb.BaudRate = 9600; // 波特率:9600 (For 485总线)
dcb.ByteSize = 8; // 数据位数:8位
dcb.Parity = NOPARITY; // 奇偶校验:无
dcb.StopBits = 1; // 停止位:1
SetCommState(hCom, &dcb);
SetupComm(hCom, 1024, 1024);
PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
COMMTIMEOUTS tout;
memset(&tout, 0, sizeof(tout));
tout.ReadTotalTimeoutConstant = 100; // 读超时100毫秒
SetCommTimeouts(hCom, &tout);
char readBuffer[1024];
char writeBuffer[1024];
DWORD wCount; // 读取的字节数
memset(readBuffer, 0, sizeof(readBuffer));
memset(writeBuffer, 0, sizeof(writeBuffer));
if (!ReadFile(hCom, readBuffer, 50, &wCount, NULL))
{
CloseHandle(hCom);
return FALSE;
}
if(wCount > 0) // 收到数据
{
if (strstr(readBuffer, "UPDATE"))
{
// 同步
tout.ReadTotalTimeoutConstant = 60000; // 读超时60秒
SetCommTimeouts(hCom, &tout);
DWORD stime = GetTickCount();
while (TRUE)
{
if (GetTickCount() - stime > 60000) // 60秒放弃
{
CloseHandle(hCom);
return FALSE;
}
// 接收ACK信号
PurgeComm(hCom, PURGE_RXCLEAR);
ReadFile(hCom,readBuffer,3,&wCount,NULL);
if (wCount == 3)
{
readBuffer[3] = '\0';
if (strcmp(readBuffer, "ACK") == 0)
{
break; // 接收到ACK后跳出while,准备接收文件
}
}
// 发送SYN信号
strcpy(writeBuffer,"SYN\r\n");
WriteFile(hCom,writeBuffer,4,&wCount,NULL);
}
// 同步成功,发送READY,接收文件
strcpy(writeBuffer,"READY\r\n");
WriteFile(hCom,writeBuffer,5,&wCount,NULL);
// 创建临时文件
HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
CloseHandle(hCom);
return FALSE;
}
// 清空输入缓冲
PurgeComm(hCom, PURGE_RXCLEAR);
while (TRUE)
{
if (!ReadFile(hCom, readBuffer, 1024, &wCount, NULL))
{
CloseHandle(hFile);
CloseHandle(hCom);
return FALSE;
}
if (wCount > 0)
{
tout.ReadTotalTimeoutConstant = 100; // 读超时100毫秒
SetCommTimeouts(hCom, &tout);
DWORD wWritten;
WriteFile(hFile, readBuffer, wCount, &wWritten, NULL);
}
else
{
break; // 不管是否发送了文件,都可以返回TRUE
}
}
CloseHandle(hFile);
CloseHandle(hCom);
return TRUE;
}
}
CloseHandle(hCom);
return FALSE;
}
INT64 CWCELoaderDlg::GetFileVersion(CString strFileName)
{
DWORD dwLen = GetFileVersionInfoSize(strFileName.GetBuffer(256),NULL);
if (dwLen == 0)
{
return 0;
}
LPVOID lpData = new wchar_t[dwLen +1];
if (!GetFileVersionInfo(strFileName.GetBuffer(256),NULL,dwLen,lpData))
{
delete lpData;
return 0;
}
unsigned int len;
VS_FIXEDFILEINFO *lpVerInfo;
if (!VerQueryValue(lpData,_T("\\"),(void **)&lpVerInfo,&len))
{
delete lpData;
return 0;
}
INT64 FileVer = lpVerInfo->dwFileVersionMS;
FileVer <<= 32;
FileVer += lpVerInfo->dwFileVersionLS;
delete lpData;
return FileVer;
}
void CWCELoaderDlg::RunExec(unsigned short *sExe)
{
STARTUPINFO si={0};
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
if (!CreateProcess(sExe, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
DWORD dwError;
dwError = GetLastError();
CString strErrorCause;
strErrorCause.Format(_T("启动错误:%d"), dwError);
#ifdef _DEBUG
SetTimer(4,1000,NULL); // 1秒后模拟回车
#else
SetTimer(3,3000,NULL); // 3秒后退出
#endif
MessageBox(strErrorCause);
return;
}
ShowWindow(SW_HIDE);
}
void CWCELoaderDlg::OnTimer(UINT nIDEvent)
{
switch (nIDEvent)
{
case 1: // DEBUG版
{
KillTimer(1);
// 加载目标程序
RunExec(WCEReadMWD.GetBuffer(256));
SetTimer(5,3000,NULL); // 不断检测更新
}
break;
case 2: // Release版
{
KillTimer(2);
// 更新文件
Update();
// 加载目标程序
RunExec(WCEReadMWD.GetBuffer(256));
// 退出
PostQuitMessage(0);
}
break;
case 3: // 退出程序
{
PostQuitMessage(0);
}
break;
case 4: // 模拟回车
{
KillTimer(4);
keybd_event(VK_RETURN, 0, 0, 0);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
}
break;
case 5:
{
// 更新文件
if (Update())
{
RunExec(WCEReadMWD.GetBuffer(256));
}
}
break;
default:
break;
}
CDialog::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -