Win11系统,VS2022编写数据库程序,小体积,绿色单文件,支持密码保护,XP到Win11都能运行
在WIN11中用VS2022编写 小体积的绿色单文件,支持密码保护,XP到WIN11都能运行的数据库程序
1. 用VC60 建立一个Win32工程,VC60建立的工程默认是字节型的。
2. 用VS2010 读取并转换为2010格式,再用VS2022 读取,选择SDK和平台都不升级
3. 把 wxsqlite3-4.5.1.zip\wxsqlite3-4.5.1\sqlite3secure\src 整个目录复制到工程的工作目录。 (更高版本的wxsqlite3的结构不同)
4. 工程属性页配置VC++路径,include和source都加入wxsqlite3的路径
5. 把sqlite3.h和sqlite3secure.c加入工程,对sqlite3secure.c设置属性不使用预编译头
6.工程属性页的c/c++ 预处理定义中增加wxsqlite3的开关
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_HAS_CODEC=1
SQLITE3ENCRYPT_EXPORTS
SQLITE_ENABLE_FTS3
SQLITE_ENABLE_FTS3_PARENTHESIS
SQLITE_SECURE_DELETE
SQLITE_SOUNDEX
CODEC_TYPE=CODEC_TYPE_AES256
7.如果程序用到了WIN32 rebar工具调,在预定义头文件stdafx.h中增加版本定义
#define WINVER 0x500 // for win95 Rebar
#define _WIN32_WINNT 0x500 // for win95
8.对于wxsqlite3,相比普通的sqlite3在打开数据库后增加调用密码
rc = sqlite3_open(filename, &m_db);
rc = sqlite3_key(m_db,"password",8); //使用密码,第一次为设置密码,以后为解密,最后参数是密码长度
9.尽量不要用图形化编程,纯代码是最通用的。
程序运行如图,测试在win11和XP中都能单个EXE文件正常运行,不需要额外的DLL
整个程序因为是模仿MFC的C++封装SDK API,框架的代码有点长,主要就是把sqlite3的几个函数放在类里。调用执行。
#pragma once #include "sqlite3.h" class CwxSQLite { public: CwxSQLite(void); ~CwxSQLite(void); public: sqlite3* m_db; char** m_sresult; BOOL m_IsOpen; public: BOOL Open(char* filename); void Close(); BOOL Query(char* sql, int &nrow, int &ncolum); BOOL OnSqlExec(char* sql); static int sqlcallback(void* NotUsed, int argc, char** argv, char** azColName); };
#include "StdAfx.h" #include "wxSQLite.h" CwxSQLite::CwxSQLite(void) { m_sresult = NULL; m_db = NULL; m_IsOpen = FALSE; } CwxSQLite::~CwxSQLite(void) { if (NULL != m_sresult) { sqlite3_free_table(m_sresult); m_sresult = NULL; } if (NULL != m_db) { sqlite3_close(m_db); m_db = NULL; } m_IsOpen = FALSE; } BOOL CwxSQLite::Open(char* filename) { int rc; if (NULL != m_db) { sqlite3_close(m_db); m_db = NULL; m_IsOpen = FALSE; } rc = sqlite3_open(filename, &m_db); if (rc) { sqlite3_close(m_db); return FALSE; } else { //m_IsOpen = TRUE; } rc = sqlite3_key(m_db,"password",8); //使用密码,第一次为设置密码,以后为解密,最后是密码长度 //rc = sqlite3_rekey(m_db,NULL,0); //清空密码 m_IsOpen = TRUE; return TRUE; } void CwxSQLite::Close() { if (NULL != m_db) { sqlite3_close(m_db); m_db = NULL; } m_IsOpen = FALSE; } //查询SQL BOOL CwxSQLite::Query(char* sql, int& nrow, int& ncolum) { char* szErrMsg; int rc; if (NULL != m_sresult) { sqlite3_free_table(m_sresult); m_sresult = NULL; } rc = sqlite3_get_table(m_db, sql, &m_sresult, &nrow, &ncolum, &szErrMsg); /* execute SQL statement */ if (rc != SQLITE_OK) { if (NULL != szErrMsg) { //PRINT(_T("\r\n<ERR>SQL error: %s\n"), szErrMsg); sqlite3_free(szErrMsg); return FALSE; } //PRINT(_T("\r\n<OK>select success!")); } return TRUE; } //sql执行回调函数 int CwxSQLite::sqlcallback(void* NotUsed, int argc, char** argv, char** azColName) { int i; for (i = 0; i < argc; i++) { //PRINT(_T("%s = %s\n"), azColName[i], argv[i] ? argv[i] : "NULL"); } //PRINT(_T("\r\n")); return 0; } //执行SQL BOOL CwxSQLite::OnSqlExec(char* sql) { char* szErrMsg; int rc; //strcpy(sql,"create table TStock(StockCode text, Time text, RealValue real );"); rc = sqlite3_exec(m_db, sql, sqlcallback, 0, &szErrMsg); /* execute SQL statement */ if (rc != SQLITE_OK) { sqlite3_free(szErrMsg); return FALSE; } return TRUE; }