如何在VBA中安全地存储连接字符串详细信息

Shi*_*iva 14 vba connection-string

我有一个Excel模板,在VBA代码中具有硬编码的Ms Access MDB路径,用于连接到Access表并保存,检索数据.

我将MS Access数据库迁移到具有Excel模板用户的集成身份验证的SQL Server.

我的问题是,存储SQL Server数据库连接字符串并在Excel 2007 VBA中检索以保存和检索数据的建议方式/最佳实践是什么?

过去,我做了以下工作.

  1. 使用具有连接字符串的注册表项设置.然后在VBA中,编写一个读取注册表项并返回连接字符串的函数.

  2. 在Excel模板中有一个"设置"隐藏工作表,其中包含连接字符串的命名单元格.通过访问该命名范围来读取VBA中的连接字符串.

  3. 使用与Excel模板一起使用的.INI txt文件.(这不是理想的,我想避免这种情况,因为它构建了对该外部文件的依赖)

我不喜欢#1,因为我想尽可能避免写入/读取注册表.#2感觉还不错,以为我不确定是否有更好的"清洁"方式来做到这一点.

有什么想法吗?

小智 30

这是我会安全地存储连接字符串凭据

下载并安装适用于Windows的Visual Studio Express 2012(免费)

以管理员身份打开它并创建一个新项目.Visual C#然后选择Class Library并重命名为HiddenConnectionString

在此输入图像描述

解决方案资源管理器中,重命名Class1.csMyServer.cs

在此输入图像描述

MyConnectionSolution Explorer中右键单击您的项目,然后选择Add Reference

键入activeX在搜索框中,并勾选Microsoft ActiveX Data Objects 6.1 Library

在此输入图像描述

将以下代码复制并粘贴到MyServer.cs完全替换文件中的任何内容中.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.IO;
using ADODB;

namespace HiddenConnectionString
{
    [InterfaceType(ComInterfaceType.InterfaceIsDual),
    Guid("2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E")]
    public interface IMyServer
    {
        Connection GetConnection();
        void Shutdown();
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("57BBEC44-C6E6-4E14-989A-B6DB7CF6FBEB")]
    public class MyServer : IMyServer
    {
        private Connection cn;

        private string cnStr = "Provider=SQLOLEDB; Data Source=SERVER\\INSTANCE; Initial Catalog=default_catalog; User ID=your_username; Password=your_password";

        public MyServer()
        {
        }

        public Connection GetConnection()
        {
            cn = new Connection();
            cn.ConnectionString = cnStr;
            cn.Open();
            return cn;
        }

        public void Shutdown()
        {
            cn.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

cnStr在代码中找到变量并更新连接字符串详细信息.

右键单击Solution Explorer中*HiddenConnectionString*解决方案,然后选择Properties.

单击Application左侧的选项卡,然后Assembly Info勾选Make Assembly COM-Visible

在此输入图像描述

单击*Build*左侧菜单中的并勾选Register For COM Interop

在此输入图像描述

注意:如果您正在为64位Office开发,请确保Platform TargetBuild菜单更改为x64!这对于64位Office COM库是必需的,以避免任何与ActiveX相关的错误.


右键单击HiddenConnectionString解决方案资源管理器,然后选择Build从菜单.

如果一切OK,然后你HiddenConnectionString.dllHiddenConnectionString.tlb应成功生成.现在就去这条路

C:\Users\administrator\Documents\Visual Studio 2012\Projects\HiddenConnectionString\HiddenConnectionString\bin\Debug
Run Code Online (Sandbox Code Playgroud)

你应该看到你的文件.

在此输入图像描述


现在打开Excel并转到VBE.单击Tools并选择References.

单击Browse按钮并导航到HiddenConnectionString.tlb.

另外,添加引用Microsoft ActiveX Object 6.1 Library- 这样就可以使用ADODB库了.

在此输入图像描述

现在右键单击Project Explorer窗口中的任意位置并插入一个新的Module

将以下代码复制并粘贴到其中

Option Explicit

Sub Main()

    Dim myCn As MyServer
    Set myCn = New MyServer

    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset

    rs.Open "Select * from [TABLE_NAME]", myCn.GetConnection

    Range("A1").CopyFromRecordset rs

    rs.Close
    myCn.Shutdown

    Set rs = Nothing
    Set myCn = Nothing

    Columns.AutoFit

End Sub
Run Code Online (Sandbox Code Playgroud)

[TABLE_NAME]数据库中的实际表名替换为.

F5或击中功能区上的绿色播放按钮.

在此输入图像描述

如果一切正常,您现在应该在电子表格上看到返回的表格.

我的样本:

在此输入图像描述


如你看到的.添加对您自己的COM库的引用并在编译中存储登录凭据和其他敏感数据.dll可保护您的数据(连接字符串).对*.dll文件进行反编译以获取任何合理的信息非常困难.有各种编码技术可以保护你的*.dll更多,但我现在不打算详细介绍.这本身就达到了你的要求.

myCn.GetConnection返回在ADODB.Connection引用的COM库中初始化的对象.不会向Excel用户显示连接字符串或敏感数据(实际上没有其他人也没有).

您可以修改C#代码以接受来自VBA的参数,即登录,密码,初始目录,要执行的查询等...如果您的用户在SQL Server实例上具有不同的权限,那么允许它不是一个坏主意人们登录.


注意:C#代码和VBA中没有添加错误处理.如果您打算使用我上面描述的技术,我强烈建议您继续努力.


  • @mehow感谢您的详细解答.正如您所看到的,这是在3年多前,我不再从事该项目或客户,但我仍然接受了您的答案.看起来它会起作用. (2认同)
  • @Shiva谢谢.无论如何我决定给出这个答案,因为我在某个时间点找不到自己的答案.希望它能很好地服务于他人:) (2认同)
  • 抱歉,这还只是安全感的错觉。事实上,它让你更容易* 进入你的数据库,因为你可以只引用你的 COM 对象并使用 *that* 来获得你自己的原始连接。 (2认同)