EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

萧闫子 发表于 2014-1-14 10:18:32

免费的删除文档中的VBA程序的工具及源码

前一段时间我写了篇文章"关于以前写的VBA在新版本64位Inventor中无法使用的问题",然后就对Structure Storage API似乎有一发不可收拾的兴趣。这一次我打算使用Structure Storage API来做个有效、方便的工具来删除Inventor文件中的VBA。Inventor文件是基于Structure Storage的,或者说IStorage/IStream。这类文件有些人翻译成复合文件。这一类型的文件都支持structure storage API,因此我们就可以用structure storage API来修改文件(内部包含的属性、信息)。IStorage是一种COM接口,能用C++调用,如果你对如何用C++调用IStorage接口来删除VBA程序感兴趣,我建议你看看Brian的博客:http://modthemachine.typepad.com/my_weblog/2009/01/removing-vba-document-projects-from-inventor-files.html我今天要讲的是C#调用IStorage接口。为了调用IStorage接口,我们要先给这个COM接口做一个.NET封装(wrapper),下面我会贴出C#的封装源代码,以及我的程序中主要的实现代码供大家参考:IStorage 的C#封装:static extern intStgIsStorageFile(string pwcsName);
static extern intStgCreateDocfile(string pwcsName, STGM grfMode, uint reserved, out IStorageppstgOpen);
static extern int StgOpenStorage( string pwcsName, IStorage pstgPriority, STGM grfMode, IntPtr snbExclude, uint reserved, out IStorage ppstgOpen);
private ArrayList fileList = new ArrayList();
public SSProcessor(ArrayList _fileList){SetFileList(_fileList);}
private void SetFileList(ArrayList _fileList){fileList = _fileList;}
public void CullFiles(){int count = 0;
foreach (FileSystemInfo file in fileList){try{StgIsStorageFile(file.FullName);count++;}catch{fileList.RemoveAt(count);//add code to log non-storagefile items}}}

public enum STGM : uint{STGM_READ = 0x00000000,STGM_WRITE = 0x00000001,STGM_READWRITE = 0x00000002,STGM_SHARE_DENY_NONE = 0x00000040,STGM_SHARE_DENY_READ = 0x00000030,STGM_SHARE_DENY_WRITE = 0x00000020,STGM_SHARE_EXCLUSIVE = 0x00000010,STGM_PRIORITY = 0x00040000,STGM_CREATE = 0x00001000,STGM_CONVERT = 0x00020000,STGM_FAILIFTHERE = 0x00000000,STGM_DIRECT = 0x00000000,STGM_TRANSACTED = 0x00010000,STGM_NOSCRATCH = 0x00100000,STGM_NOSNAPSHOT = 0x00200000,STGM_SIMPLE = 0x08000000,STGM_DIRECT_SWMR = 0x00400000,STGM_DELETEONRELEASE = 0x04000000,}

public enum STGC : uint{STGC_DEFAULT = 0,STGC_OVERWRITE = 1,STGC_ONLYIFCURRENT = 2,STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,STGC_CONSOLIDATE = 8}
public enum STATFLAG : uint{STATFLAG_DEFAULT = 0,STATFLAG_NONAME = 1}
public interface IEnumSTATSTG{// The user needs to allocate an STATSTG array whose size is celt.uintNext(uint celt,//out ComTypes.STATSTG rgelt,out uint pceltFetched);
void Skip(uint celt);
void Reset();
IEnumSTATSTG Clone();}
public interface IStorage{void CreateStream(/* */ string pwcsName,/* */ STGM grfMode,/* */ uint reserved1,/* */ uint reserved2,/* */ out IStream ppstm);
void OpenStream(/* */ string pwcsName,/* */ IntPtr reserved1,/* */ STGM grfMode,/* */ uint reserved2,/* */ out IStream ppstm);
void CreateStorage(/* */ string pwcsName,/* */ STGM grfMode,/* */ uint reserved1,/* */ uint reserved2,/* */ out IStorage ppstg);
void OpenStorage(/* */ string pwcsName,/* */ IStorage pstgPriority,/* */ STGM grfMode,/* */ IntPtr snbExclude,/* */ uint reserved,/* */ out IStorage ppstg);
void CopyTo(/* */ uint ciidExclude,///* */ Guid rgiidExclude,//Guid[] rgiidExclude,IntPtr rgiidExclude,///* */ IntPtr snbExclude,//string[] snbExclude,//IntPtr[] snbExclude,IntPtr snbExclude,/* */ IStorage pstgDest);
void MoveElementTo(/* */ string pwcsName,/* */ IStorage pstgDest,/* */ string pwcsNewName,/* */ uint grfFlags);
void Commit(/* */ STGC grfCommitFlags);
void Revert();
void EnumElements(/* */ uint reserved1,/* */ IntPtr reserved2,/* */ uint reserved3,/* */ out IEnumSTATSTG ppenum);
void DestroyElement(/* */ string pwcsName);
void RenameElement(/* */ string pwcsOldName,/* */ string pwcsNewName);
void SetElementTimes(/* */ string pwcsName,/* */ ComTypes.FILETIME pctime,/* */ ComTypes.FILETIME patime,/* */ ComTypes.FILETIME pmtime);
void SetClass(/* */ Guid clsid);
void SetStateBits(/* */ uint grfStateBits,/* */ uint grfMask);
void Stat(/* */ out ComTypes.STATSTG pstatstg,/* */ STATFLAG grfStatFlag);}调用IStorage来删除VBA代码的函数(节点RSeStorage/RSeEmbeddings/apc) :public void ProcessFiles(){foreach (FileSystemInfo file in fileList){// Open the file as a storage.IStorage stg;IStorage stg_new;
int result = StgOpenStorage(file.FullName, null, STGM.STGM_DIRECT | STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE, IntPtr.Zero, 0, out stg);

// Find the storage with the path "RSeStorage/RSeEmbeddings/apc"stg.OpenStorage("RSeStorage", null, STGM.STGM_DIRECT | STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE, IntPtr.Zero, 0, out stg_new);
if (stg_new == null){System.Windows.Forms.MessageBox.Show("can't find RSeStorage node");return;}stg_new.OpenStorage("RSeEmbeddings", null, STGM.STGM_DIRECT | STGM.STGM_READWRITE | STGM.STGM_SHARE_EXCLUSIVE, IntPtr.Zero, 0, out stg);if (stg == null){System.Windows.Forms.MessageBox.Show("can't find RSeEmbeddings node");return;}ComTypes.STATSTG s1 = new ComTypes.STATSTG();IEnumSTATSTG SSenum;stg.EnumElements(0, IntPtr.Zero, 0, out SSenum);
uint NumReturned = 0;do{SSenum.Next(1, out s1, out NumReturned);if (NumReturned > 0){if (s1.pwcsName == "apc"){// Delete the storagestg.DestroyElement("apc");stg.Commit(STGC.STGC_DEFAULT);break;}}} while (NumReturned > 0);}System.Windows.Forms.MessageBox.Show("VBA project has been deleted!");}调用上面的函数的代码:ArrayList fileList;// Open the storage and read from storageif (fileList.Count > 0){SSProcessor ssProc = new SSProcessor(fileList);ssProc.ProcessFiles();}实现选择文件功能:try{FolderBrowserDialog folderDlg = new FolderBrowserDialog();folderDlg.Description = "选择文件夹";
DialogResult res = folderDlg.ShowDialog(this);if (res == DialogResult.OK){fileList.Clear();this.listBox1.Items.Clear();//Get the Directory Info using Directory NameDirectoryInfo dirInfor = new DirectoryInfo(folderDlg.SelectedPath);FileInfo[] partFiles = dirInfor.GetFiles("*.ipt");foreach (FileInfo fInfo in partFiles){this.listBox1.Items.Add(fInfo.FullName);fileList.Add(fInfo);}FileInfo[] assFiles = dirInfor.GetFiles("*.iam");foreach (FileInfo fInfo in assFiles){this.listBox1.Items.Add(fInfo.FullName);fileList.Add(fInfo);}FileInfo[] drFiles = dirInfor.GetFiles("*.idw");foreach (FileInfo fInfo in drFiles){this.listBox1.Items.Add(fInfo.FullName);fileList.Add(fInfo);}}}catch (Exception ex) { MessageBox.Show(ex.Message); }简单的执行界面图: http://hi.csdn.net/attachment/201005/25/0_12747613755zFi.gif
你也可以到我的资源中心(http://barbarahan.download.csdn.net/)去下载完整的源码deleteVBA_C#_source和执行程序deleteVBA_C#_exe。(我刚才上传了exe资源,但是CSDN没有显示,也许等你看的时候就出来了。)
文章来源:http://blog.csdn.net/barbarahan

EaBIM门户编辑 发表于 2017-5-19 10:13:11

什么时候学习都不晚

妮可 发表于 2016-3-7 09:51:00

☆⌒(*^-゜)v THX!!

楚客 发表于 2014-9-5 15:20:51

路过!!!
不发表意见……

悠悠筱荷 发表于 2014-2-18 12:16:17

顶!!!!!!!!!!!!!!!!!!!!!!!!!

苦田辛君 发表于 2014-2-18 12:20:17

(*^__^*) 嘻嘻……

妮可 发表于 2014-2-18 12:21:38

(*^__^*) 嘻嘻……

gba8297517 发表于 2014-2-18 12:30:32

顶!!!!!!!!!!

毫半字 发表于 2014-2-18 12:33:14

顶!!!!!!!!!!

OK佬 发表于 2014-2-19 15:00:35

(*^__^*) 嘻嘻……

教父 发表于 2014-2-21 14:45:56

路过!!!
不发表意见……

看看侃侃 发表于 2014-2-22 20:17:47

(*^__^*) 嘻嘻……

猫猫girl 发表于 2014-2-25 10:37:26

顶起来…………

MIMDxFzL 发表于 2014-2-25 10:40:13

(*^__^*) 嘻嘻……

zj1345 发表于 2014-2-28 11:53:51

顶起来…………

AK47 发表于 2014-3-5 15:37:34

顶......
楼下跟上.....

NetBeetle 发表于 2014-3-5 15:40:19

(*^__^*) 嘻嘻……

苦田辛君 发表于 2014-3-7 11:58:44

顶......
楼下跟上.....
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 免费的删除文档中的VBA程序的工具及源码