Win11系统,VS2022编写数据库程序,小体积,绿色单文件,支持密码保护,XP到Win11都能运行

发布时间 2023-05-03 10:13:51作者: XGZ21

在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;
}