|
本帖最后由 wangjian6931 于 2013-2-12 21:47 编辑
大家好,好久没有到论坛上提问了,这次实在是在网上找不到更容易实现的保护代码的方案了。可能是我太较真了,就是想找到一个方法可以保护好自己写的代码,可是又不想封装到Dll里面那么费事。在这里想寻求大家的帮助,一起来讨论讨论到底怎样可以把代码更好的保护好。
我在网上也寻找了好多方案,在这里列出来与大伙先共享一下:
1.EXCEL作品封装实例(二)-更完美的封装方案
http://club.excelhome.net/forum.php?mod=viewthread&tid=25172
特点:
EXCEL内部的封装主要是去掉原来的菜单、工具,安装上自己的菜单及工具,尽量让人一眼看起来不象EXCEL的样子,例如可以去掉EXCEL的左上角图标,状态编辑栏、行号列标、工作表标签、滚动条,最好在第一页配上背景。总之应以让人看不出是EXCEL作为目的。二、外部封装制作启动图标、启动封面、用VB等工具来打开EXCEL作品,从而避开EXCEL的宏对话框,同时将VB代码编译成可执行文件。用QuickCHM制作EXCEL作品的帮助文件,并且能使其在EXCEL中被打开。最后使用Wise Installation System 将VB可执行文件、帮助文件、EXCEL作品打包成安装文件。
这个方案我总想知道Excel文件本身放哪呀?放在明显的地方不怕被人破解呀?
2.EXCEL封装实例(三)-完善+完美的封装方案
http://club.excelhome.net/forum.php?mod=viewthread&tid=27119
特点:
附件没有下载到,我不知道这一方案的优点在哪里
3.VBA封装最佳方案实践
http://club.excelhome.net/thread-620436-1-1.html
特点:
创建主程序EXE,主要实现宿主程序加载和对账模块的加载,包含登录界面,登录界面,以及自动升级,我这里是写一个xla文档来加载对账模块(DLL)加载时自动完成自定义菜单,工具条的装载配置,加载后已完全看不到EXCEL的影子,xla是作为资源文件封装在EXE中,运行时自动释放,退出将自动删除,这个xla相当于完成EXCEL和DLL的一个接口功能,菜单和工具条均定义在后台数据库中来动态配置,只要程序运行,用户根本无法截或和进入VBA工程
方案是挺好的,能不能把封装代码跟我们分享分享呢?
4.Excel开发超人培训班开张(已加动画、还原数据库工具)
http://club.excelhome.net/thread-485100-1-1.html
特点:
这个帖子里的封装方案是用VB6做一个界面,然后把存在SQL Server数据库中的Excel文件读取到内存。主要代码在Dll文件及启动程序内。
这个方案挺好的,我个人挺喜欢,可是个人水平问题,我猜不出没有任何VBA代码的Excel文件的右击事件是如何调用的(代码放在VB主程序内?用VB主程序检测鼠标事件?)。
5.Dll封装代码
特点:
将自己的代码写成类文件,并用VB6将代码封装到Dll里面。
这个就不找帖子示例了,一找一大把,用Dll封装的话代码的安全性应该是有的,难度也不是特别大。可是问题是,我们在写代码的时候可能经常性的对代码作微调,来回封装很是麻烦。我想达到的目的是,VBA代码直接还是放在Excel文件里,然后想办法把Excel文件本身藏起来。
下面我利用前人已有的方案考虑了一个新的方案:
6.VB6做启动程序+Excel界面及主程序代码+数据库存放Excel文件
粗看这个方案跟第一、第三、第四方案都差不多:用VB6做启动文件,避开是否启用宏的提示;Excel文件存在数据库中,一般人不太容易找到原文件,可是找到了就麻烦了;某天访问论坛看到虎版的二进制读写文件的示例,突然想到是否可以把Excel文件存成数值型的数据,然后再搞乱顺序及再加一些干扰数据,最后再把它还原回来。我试了一下文件小的还可以,可是文件一大的话速度就慢了,可能是我的代码问题吧,希望哪位大大可以把速度优化了并将代码与大伙分享一下。附虎版的二进制读写文件的代码示例,实在不好意思,原贴我找不到了。
- Sub 从EXCEL提取数据生成文件()
- Dim arr() As Byte, ar, a&, X&, Y%, j&
- a = Range("iv1").End(xlToLeft).Column
- ar = Range(Cells(1, 1), Cells(65536, a))
- For Y = 1 To a
- For X = 1 To 65536
- If ar(X, Y) <> "" Then
- j = j + 1
- ReDim Preserve arr(1 To j)
- arr(j) = ar(X, Y)
- End If
- Next X
- Next Y
- Open ThisWorkbook.Path & "\a.wav" For Binary As #1
- Put #1, , arr
- Close #1
- MsgBox "当前目录下已经生成了文件a.wav"
- End Sub
- Sub 文件的数据保存到EXCEL中()
- Dim arr() As Byte, X&, i&, j%, ar(), H&
- Cells.ClearContents
- Open ThisWorkbook.Path & "\a.wav" For Binary As #1
- H = LOF(1)
- ReDim arr(1 To H)
- Get #1, , arr
- Close #1
- j = 1
- ReDim ar(1 To 65536, 1 To j)
- Close #1
- For X = 1 To H
- i = i + 1
- If i > 65536 Then
- j = j + 1
- i = 1
- ReDim Preserve ar(1 To 65536, 1 To j)
- End If
- ar(i, j) = arr(X)
- Next X
- [a1].Resize(65536, j) = ar
- End Sub
复制代码 先附上用AutoIT V3做的启动程序代码
- $cn =ObjCreate("ADODB.Connection")
- $cn.Open ("Driver={SQL Server};Server=WS03-20121214YC;uid=stock_login;pwd=jianwang6931;database=stock")
- $rs =ObjCreate("ADODB.Recordset")
- $RS.ActiveConnection = $cn ; 设定RS 是 conn 的集合 重要的部份
- $rs.Open(" Select * from file_name ")
-
- $mstream =ObjCreate("ADODB.Stream")
- $mstream.Type =1
- $mstream.Open
- $mstream.Write($rs.Fields("file_itself").Value)
- $mstream.SaveToFile ("c:\publogo.xls", 2)
- $rs.Close
- $cn.Close
- Local $oExcel = ObjCreate("Excel.Application")
- $oExcel.Workbooks.Open ("c:\publogo.xls")
- $oExcel.visible=True
复制代码 VB中的代码
[code=vb]Sub SaveToDB()
'将硬盘中的数据保存到数据库当中
Dim iStm As ADODB.Stream
Dim RS As ADODB.Recordset
Dim StrSqls As String
Set iStm = New ADODB.Stream
With iStm
.Type = adTypeBinary
.Open
.LoadFromFile (Application.GetOpenFilename("Text Files (*.xls), *.xls"))
End With
Set conn = CreateObject("ADODB.CONNECTION")
conn.Open conn_SqlServer
Set RS = CreateObject("ADODB.Recordset")
StrSqls = "select * from file_name "
RS.Open StrSqls, conn, 3, 3
RS.AddNew
RS!file_itself = iStm.Read
RS.Update
RS.Close
iStm.Close
End Sub
Sub SaveToFile()
'将数据库的二进制文件保存到硬盘中并打开
Dim iStm As ADODB.Stream
Dim RS As ADODB.Recordset
Dim StrSqls As String, FilePath As String
Set conn = CreateObject("ADODB.CONNECTION")
conn.Open conn_SqlServer
Set RS = CreateObject("ADODB.Recordset")
StrSqls = "select * from file_name "
RS.Open StrSqls, conn, 3, 3
Set iStm = New ADODB.Stream
FilePath = Application.GetSaveAsFilename("Text Files (*.xls), *.xls")
With iStm
.Mode = adModeReadWrite
.Type = adTypeBinary
.Open
.Write (RS.Fields("file_itself"))
.SaveToFile (FilePath)
End With
iStm.Close
RS.Close
Set Myexcel = CreateObject("Excel.Application")
Myexcel.Workbooks.Open (FilePath)
Myexcel.Visible = True
'在工作簿的Workbook_Open()事件中加入以下代码以达到删除原文件的目的
'ActiveWorkbook.ChangeFileAccess xlReadOnly
'Kill ActiveWorkbook.FullName
End Sub[/code]
以下为方案6做出来的效果,可是问题是代码处理大文件时,速度太慢让人无法接受,希望有高手能帮忙看看是否有优化的空间,在此附上图片及代码附件。
读写文件.rar
(35.06 KB, 下载次数: 103)
附件中是将文件以Byte类型保存到SQL Server数据库中,保存时会先将之前的数据表删除新建数据表。可根据自己的意愿将数据保存多少列。保存的列数越多越安全。
程序会将随机将数据保存到数据库中,并将未来要查询的SQL语句同时生成,将来要查询出该文件必须保存此SQL语句。
目前在想是否可以将大文件分割乱序以二进制Image类型保存到SQL Server数据库中,再在部分二进制文件中做点手脚,然后再作读写操作,那样速度应该不错,希望哪位大侠会做,或者直接有这样的代码可以共享出来。
7.其他方案:
用AutoIT V3的工具,将Excel文件本身转化为16进制的文本存成代码文本,要用时将Excel文件再写到临时文件夹内,再用VBA代码将文件读入内存后,删除文件自身,屏蔽常用查看代码的热键……以达到保护自身的目的。问题关键处是,现在AutoIT V3这个自动化的软件可以被反编译了,写的代码会被人看得清清楚楚。不过可以糊弄一些不知道是什么东西封装的人。内行的人可以试试按键精灵,如果谁做好了真希望能拿出来跟大家一起分享一下。
以下为AutoIT V3的代码(文件部分不全,全了的话会很长,只是个样式示范):
- FileWrite("C:\Documents and Settings\Administrator\桌面\MyDTPicker.xls",MyDTPicker_xls())
- Local $oExcel = ObjCreate("Excel.Application")
- $oExcel.Workbooks.Open ("C:\Documents and Settings\Administrator\桌面\MyDTPicker.xls")
- $oExcel.visible=True
- Func MyDTPicker_xls()
- Local $FileBin=""
- $FileBin &="D0CF11E0A1B11AE1000000000000000000000000000000003E000300FEFF0900060000000000000000000000020000000100000000000000001000000200000003000000FEFFFFFF000000000000000074000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $FileBin &="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $FileBin &="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $FileBin &="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $FileBin &="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
- $FileBin &="FFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFF16000000260000001700000005000000060000000700000008000000090000000A0000000B0000000C0000000D0000000E0000000F000000100000001100000012000000130000001400000015000000FEFFFFFF"
- $FileBin &="1E00000018000000190000001A0000001B0000001C0000001D0000001F00000059000000200000002100000022000000230000006C0000002500000027000000E700000028000000440000002A0000002B0000002C0000002D0000002E0000002F000000"
- $FileBin &="300000003100000032000000330000003400000035000000360000003700000038000000390000003A0000003B0000003C0000003D0000003E0000003F000000400000004100000042000000430000002400000045000000460000004700000048000000"
- $FileBin &="E6150B000B000000000000000B000000000000000B000000000000000B000000000000001E100000030000000700000053686565743100070000005368656574320007000000536865657433000C100000020000001E00000007000000B9A4D7F7B1ED00"
- $FileBin &="030000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100FEFF030A0000FFFFFFFF2008020000000000C0000000000000461E0000004D696372"
- $FileBin &="6F736F6674204F666669636520457863656C20B9A4D7F7B1ED00060000004269666638000E000000457863656C2E53686565742E3800F439B27100000000000000000000000000000000000000000000000000000000000000000000"
- Return Binary("0x" & $FileBin)
- EndFunc
复制代码 也许大家看了有点晕,个人表达水平问题,将就一下吧。
再次声明我的立场:目前有很好的保护方案,可是Dll方案感觉有点麻烦,其他的方案没人提供原代码,在这里呼吁一下,希望高手能够把自己的方案与大家分享一下。最好能够分享一下自己的代码。如果实在舍不得分享代码,能把思路方案分享一下也行。
|
|