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

EaBIM

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 8584|回复: 134
打印 上一主题 下一主题

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

[复制链接]

1514

主题

7465

帖子

1万

积分

admin

Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10

积分
12404

社区QQ达人

跳转到指定楼层
楼主
发表于 2014-1-14 10:18:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

前一段时间我写了篇文章"关于以前写的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#封装:

[DllImport("ole32.dll")]

static extern int

StgIsStorageFile([MarshalAs(UnmanagedType.LPWStr)]

string pwcsName);


[DllImport("ole32.dll")]

static extern int

StgCreateDocfile([MarshalAs(UnmanagedType.LPWStr)]

string pwcsName, STGM grfMode, uint reserved, out IStorage

ppstgOpen);


[DllImport("ole32.dll")]

static extern int StgOpenStorage(

[MarshalAs(UnmanagedType.LPWStr)] 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

}


[ComImport]

[Guid("0000000d-0000-0000-C000-000000000046")]

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]

public interface IEnumSTATSTG

{

// The user needs to allocate an STATSTG array whose size is celt.

[PreserveSig]

uint

Next(

uint celt,

//[MarshalAs(UnmanagedType.LPArray), Out]

out ComTypes.STATSTG rgelt,

out uint pceltFetched

);


void Skip(uint celt);


void Reset();


[return: MarshalAs(UnmanagedType.Interface)]

IEnumSTATSTG Clone();

}


[ComImport]

[Guid("0000000b-0000-0000-C000-000000000046")]

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown )]

public interface IStorage

{

void CreateStream(

/* [string][in] */ string pwcsName,

/* [in] */ STGM grfMode,

/* [in] */ uint reserved1,

/* [in] */ uint reserved2,

/* [out] */ out IStream ppstm);


void OpenStream(

/* [string][in] */ string pwcsName,

/* [unique][in] */ IntPtr reserved1,

/* [in] */ STGM grfMode,

/* [in] */ uint reserved2,

/* [out] */ out IStream ppstm);


void CreateStorage(

/* [string][in] */ string pwcsName,

/* [in] */ STGM grfMode,

/* [in] */ uint reserved1,

/* [in] */ uint reserved2,

/* [out] */ out IStorage ppstg);


void OpenStorage(

/* [string][unique][in] */ string pwcsName,

/* [unique][in] */ IStorage pstgPriority,

/* [in] */ STGM grfMode,

/* [unique][in] */ IntPtr snbExclude,

/* [in] */ uint reserved,

/* [out] */ out IStorage ppstg);


void CopyTo(

/* [in] */ uint ciidExclude,

///* [size_is][unique][in] */ Guid rgiidExclude,

//Guid[] rgiidExclude,

IntPtr rgiidExclude,

///* [unique][in] */ IntPtr snbExclude,

//string[] snbExclude,

//IntPtr[] snbExclude,

IntPtr snbExclude,

/* [unique][in] */ IStorage pstgDest);


void MoveElementTo(

/* [string][in] */ string pwcsName,

/* [unique][in] */ IStorage pstgDest,

/* [string][in] */ string pwcsNewName,

/* [in] */ uint grfFlags);


void Commit(

/* [in] */ STGC grfCommitFlags);


void Revert();


void EnumElements(

/* [in] */ uint reserved1,

/* [size_is][unique][in] */ IntPtr reserved2,

/* [in] */ uint reserved3,

/* [out] */ out IEnumSTATSTG ppenum);


void DestroyElement(

/* [string][in] */ string pwcsName);


void RenameElement(

/* [string][in] */ string pwcsOldName,

/* [string][in] */ string pwcsNewName);


void SetElementTimes(

/* [string][unique][in] */ string pwcsName,

/* [unique][in] */ ComTypes.FILETIME pctime,

/* [unique][in] */ ComTypes.FILETIME patime,

/* [unique][in] */ ComTypes.FILETIME pmtime);


void SetClass(

/* [in] */ Guid clsid);


void SetStateBits(

/* [in] */ uint grfStateBits,

/* [in] */ uint grfMask);


void Stat(

/* [out] */ out ComTypes.STATSTG pstatstg,

/* [in] */ 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 storage

stg.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 storage

if (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 Name

DirectoryInfo 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://barbarahan.download.csdn.net/)去下载完整的源码deleteVBA_C#_source和执行程序deleteVBA_C#_exe。(我刚才上传了exe资源,但是CSDN没有显示,也许等你看的时候就出来了。)


文章来源:http://blog.csdn.net/barbarahan

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 转播转播 分享分享 分享淘帖 支持支持 反对反对
工作时间:工作日的9:00-12:00/13:30-18:00,节假日不在线,请勿留言
推荐
发表于 2017-5-19 10:13:11 | 只看该作者
什么时候学习都不晚

14

主题

2892

帖子

2085

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
2085
推荐
发表于 2016-3-7 09:51:00 | 只看该作者
☆⌒(*^-゜)v THX!!

11

主题

846

帖子

1772

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1772
推荐
发表于 2014-9-5 15:20:51 | 只看该作者
路过!!!
不发表意见……

0

主题

836

帖子

1198

积分

BIM项目负责人

Rank: 5Rank: 5Rank: 5Rank: 5Rank: 5

积分
1198
6F
发表于 2014-2-18 12:20:17 | 只看该作者
(*^__^*) 嘻嘻……

14

主题

2892

帖子

2085

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
2085
7F
发表于 2014-2-18 12:21:38 | 只看该作者
(*^__^*) 嘻嘻……

4

主题

846

帖子

1300

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1300
10F
发表于 2014-2-19 15:00:35 | 只看该作者
(*^__^*) 嘻嘻……

16

主题

842

帖子

1377

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1377
11F
发表于 2014-2-21 14:45:56 | 只看该作者
路过!!!
不发表意见……

8

主题

843

帖子

1340

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1340
12F
发表于 2014-2-22 20:17:47 | 只看该作者
(*^__^*) 嘻嘻……

5

主题

726

帖子

1692

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1692
14F
发表于 2014-2-25 10:40:13 | 只看该作者
(*^__^*) 嘻嘻……

12

主题

854

帖子

1923

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1923
16F
发表于 2014-3-5 15:37:34 | 只看该作者
顶......
楼下跟上.....

7

主题

861

帖子

1418

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
1418
17F
发表于 2014-3-5 15:40:19 | 只看该作者
(*^__^*) 嘻嘻……

0

主题

836

帖子

1198

积分

BIM项目负责人

Rank: 5Rank: 5Rank: 5Rank: 5Rank: 5

积分
1198
18F
发表于 2014-3-7 11:58:44 | 只看该作者
顶......
楼下跟上.....
*滑块验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|EaBIM网 ( 苏ICP备2020058923号-1  苏公网安备32011502011255号

GMT+8, 2024-11-23 11:44

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表