1 首先要使用shell32  请在项目引用中添加shell32.dll 的引用  (备注:该引用是系统dll文件 在C:\Windows\System32  目录下 可以自行拷贝到项目中)

  

private void  btnTest_Click(object sender, EventArgs e)     //测试的按钮点击事件
{ //测试,将excel中的student导入到sqlserver的DB_MES中,如果sql中的数据表不存在则创建
System.Windows.Forms.OpenFileDialog fd = new OpenFileDialog(); // new 一个打开文件对话框用于选择文件
if (fd.ShowDialog() == DialogResult.OK)
{
string filePath = fd.FileName; //实例化一个shell 对象 Shell32.Shell shell = new Shell32.ShellClass(); //获取文件所在父目录对象
Folder folder = shell.NameSpace(filePath.Substring(0, filePath.LastIndexOf('\\')));
//获取文件对应的FolderItem对象
FolderItem item = folder.ParseName(filePath.Substring(filePath.LastIndexOf('\\') + 1));
//字典存放属性名和属性值的键值关系对
Dictionary<string, string> Properties = new Dictionary<string, string>();
int i = 0;
while (true)
{
//获取属性名称
string key = folder.GetDetailsOf(null, i);
if (string.IsNullOrEmpty(key))
{
//当无属性可取时,推出循环
break;
}
//获取属性值
string value = folder.GetDetailsOf(item, i);
//保存属性
Properties.Add(key, value);
this.richTextBox1.Text += i.ToString() + key + ":" + value + '\n'; // 窗体界面上创建的richTextBox 控件上显示所有的属性值
i++;
} }

  

//------我的开的文件名是1.xls---------实际运行效果如下------根据运行结果可以查看我们需要的信息对应的索引

0名称:1.xls
1大小:16.0 KB
2项目类型:Microsoft Office Excel 97-2003 工作表
3修改日期:2017/12/22 11:35
4创建日期:2017/12/22 10:38
5访问日期:2017/12/22 11:35
6属性:A
7脱机状态:
8脱机可用性:
9假设的类型:文档
10所有者:USER-20170822CM\Administrator
11种类:文档
12拍摄日期:
13参与创作的艺术家:
14唱片集:
15年:
16流派:
17指挥者:
18标记:
19分级:未分级
20作者:Administrator
21标题:
22主题:
23类别:
24备注:
25版权:
26#:
27长度:
28比特率:
29保护:
30照相机型号:
31尺寸:
32照相机制造商:
33公司:
34文件说明:
35程序名称:
36持续时间:
37联机:
38重复:
39位置:
40可选参加者地址:
41可选的与会者:
42组织者地址:
43组织者名称:
44提醒时间:
45必选的与会者地址:
46必选的与会者:
47资源:
48会议状态:
49忙闲状态:
50总大小:
51帐户名:
52任务状态:
53计算机:USER-20170822CM (本机)
54纪念日:
55助理姓名:
56助理电话:
57生日:
58商务地址:
59公司所在市县:
60公司所在国家/地区:
61公司邮箱:
62公司所在地的邮政编码:
63公司所在省市自治区:
64公司所在街道地址:
65业务传真:
66公司主页:
67商务电话:
68回呼号码:
69车载电话:
70子女:
71公司主要电话:
72部门:
73电子邮件地址:
74电子邮件2:
75电子邮件3:
76电子邮件列表:
77电子邮件显示名称:
78文件为:
79名字:
80全名:
81性别:
82名:
83个人爱好:
84住宅地址:
85住宅所在市/县:
86住宅所在国家/地区:
87住宅邮箱:
88住宅所在地的邮政编码:
89住宅所在省市自治区:
90住宅所在街道地址:
91住宅传真:
92住宅电话:
93即时通讯地址:
94姓名缩写:
95职务:
96标签:
97姓氏:
98通讯地址:
99中间名:
100手机:
101昵称:
102办公位置:
103其他地址:
104其他市县:
105其他国家/地区:
106其他邮政信箱:
107其他邮政编码:
108其他省市自治区:
109其他街道地址:
110寻呼机:
111称谓:
112市县:
113国家/地区:
114邮箱:
115邮政编码:
116省市自治区:
117街道地址:
118主要电子邮件:
119主要电话:
120职业:
121配偶/伙伴:
122后缀:
123TTY/TTD 电话:
124Telex:
125网页:
126内容状态:
127内容类型:
128获取日期:
129存档日期:
130完成日期:
131设备类别:
132已连接:
133发现方法:
134友好名称:
135本地计算机:
136制造商:
137型号:
138已配对:
139分类:
140打印机状态:
141客户端 ID:
142参与者:
143创建内容的时间:
144最后一次打印的时间:
145最后一次保存的日期:‎2017/‎12/‎22 ‏‎11:35
146分部:
147文档 ID:
148页码范围:
149幻灯片:
150总编辑时间:
151字数:
152截止日期:
153结束日期:
154文件计数:
155文件名:1.xls
156文件版本:
157标志颜色:
158标记状态:
159可用空间:
160位深度:
161水平分辩率:
162宽度:
163垂直分辩率:
164高度:
165重要性:
166是附件:
167已删除:
168加密状态:
169有标志:
170已完成:
171不完整:
172阅读状态:
173已共享:否
174编写者:
175日期:
176文件夹名称:桌面
177文件夹路径:C:\用户\Administrator\桌面
178文件夹:桌面 (C:\用户\Administrator)
179参加者:
180路径:C:\用户\Administrator\桌面\1.xls
181依位置:
182类型:Microsoft Office Excel 97-2003 工作表
183联系人:
184条目类型:
185语言:
186访问时间:
187描述:
188链接状态:未解析
189链接目标:
190URL:
191创建媒体日期:
192发布日期:
193编码人员:
194制作人:
195发布者:
196副标题:
197用户 Web URL:
198创作人:
199附件:
200密件抄送地址:
201密件抄送:
202抄送地址:
203抄送:
204会话 ID:
205接收日期:
206发送日期:
207发件人地址:
208发件人:
209带有附件:
210发信人地址:
211发信人:
212存储:
213收件人地址:
214操作标题:
215收件人:
216里程:
217唱片集艺术家:
218唱片集 ID:
219每分钟节拍数:
220作曲者:
221初始调性:
222编译的一部分:
223氛围:
224部分设置:
225时期:
226颜色:
227家长分级:
228父级分级原因:
229已用空间:
230EXIF 版本:
231事件:
232曝光补偿:
233曝光程序:
234曝光时间:
235光圈值:
236闪光灯模式:
237焦距:
23835mm 焦距:
239ISO 速度:
240镜头制造商:
241镜头型号:
242光源:
243最大光圈:
244测光模式:
245方向:
246人员:
247程序模式:
248饱和度:
249目标距离:
250白平衡:
251优先级:
252项目:
253频道号:
254剧集名称:
255关闭字幕:
256重新运行:
257SAP:
258广播日期:
259节目描述:
260记录时间:
261电台呼叫信号:
262电台名:
263摘要:
264片段:
265自动汇总:
266搜索级别:
267敏感度:
268共享设备:
269共享状态:专用
270产品名称:
271产品版本:
272支持链接:
273源:
274开始日期:
275帐单信息:
276完成:
277任务所有者:
278总计文件大小:
279合法商标:
280视频压缩:
281导演:
282数据速率:
283帧高度:
284帧速率:
285帧宽度:
286总比特率:

  

上面的方法返回所有属性值,在我的Win7 Pro 64bit 上,返回了287个属性!可以想象,信息是很丰富的,但是速度也是够慢的。

可以看到,上面代码用了一个循环,获取属性名和属性值时都是通过i来索引的。那么,我们是不是就能不通过循环,而直接用下标来获取想要的属性呢?代码如下:

/// <summary>

        /// 获取指定文件指定下标的属性值

        /// </summary>

        /// <param name="filePath">文件路径</param>

        /// <param name="index">属性下标</param>

        /// <returns>属性值</returns>

        public static string GetPropertyByIndex(string filePath, int index)

        {

            if (!File.Exists(filePath))

            {

                throw new FileNotFoundException("指定的文件不存在。", filePath);

            }

            //初始化Shell接口 

            Shell32.Shell shell = new Shell32.ShellClass();

            //获取文件所在父目录对象 

            Folder folder = shell.NameSpace(Path.GetDirectoryName(filePath));

            //获取文件对应的FolderItem对象 

            FolderItem item = folder.ParseName(Path.GetFileName(filePath));

            string value = null;

            //获取属性名称 

            string key = folder.GetDetailsOf(null, index);

            if (false == string.IsNullOrEmpty(key))

            {

                //获取属性值 

                value = folder.GetDetailsOf(item, index);

            }

            return value;

        }

  

在我的系统环境上,分辨率“尺寸”下标是31,那么我只需要GetPropertyByIndex(fd.fileName,31)就可以获取到分辨率信息了。但是特别需要注意,“尺寸”属性的下标,在不同的Windows版本(XP,Vista,Win7,Win2003等)不一定是一样的。

ok,我们还注意到每个属性都有对应的一个“属性名”,那么,我们能不能通过属性名来获取属性值呢,这样会比使用下标保险多了吧。代码如下:

/// <summary>

        /// 获取指定文件指定属性名的值

        /// </summary>

        /// <param name="filePath">文件路径</param>

        /// <param name="propertyName">属性名</param>

        /// <returns>属性值</returns>

        public static string GetProperty(string filePath, string propertyName)

        {

            if (!File.Exists(filePath))

            {

                throw new FileNotFoundException("指定的文件不存在。", filePath);

            }

            //初始化Shell接口 

            Shell32.Shell shell = new Shell32.ShellClass();

            //获取文件所在父目录对象 

            Folder folder = shell.NameSpace(Path.GetDirectoryName(filePath));

            //获取文件对应的FolderItem对象 

            FolderItem item = folder.ParseName(Path.GetFileName(filePath));

            string value = null;

            int i = 0;

            while (true)

            {

                //获取属性名称 

                string key = folder.GetDetailsOf(null, i);

                if (string.IsNullOrEmpty(key))

                {

                    //当无属性可取时,退出循环 

                    break;

                }

                if (true == string.Equals(key, propertyName, StringComparison.CurrentCultureIgnoreCase))

                {

                    //获取属性值 

                    value = folder.GetDetailsOf(item, i);

                    break;

                }

                i++;

            }

            return value;

        }

GetProperty

  

这个方法是我一开始写的,通过在while里面加上属性名的判断,直到找到对应的属性名,则返回相应的属性值。

不过这个方法还是不够简洁,“尺寸”属性在31,意味着每一次都需要循环31次才能拿到我要的值,如果我要获取的属性名下标为287(参看上面),那么次数将更多,于是,我又对代码做了一些优化:

/// <summary>

        /// 存储属性名与其下标(key值均为小写)

        /// </summary>

        private static Dictionary<string, int> _propertyIndex = null;

        /// <summary>

        /// 获取指定文件指定属性名的值

        /// </summary>

        /// <param name="filePath">文件路径</param>

        /// <param name="propertyName">属性名</param>

        /// <returns>属性值</returns>

        public static string GetPropertyEx(string filePath, string propertyName)

        {

            if (_propertyIndex == null)

            {

                InitPropertyIndex();

            }

            //转换为小写

            string propertyNameLow = propertyName.ToLower();

            if (_propertyIndex.ContainsKey(propertyNameLow))

            {

                int index = _propertyIndex[propertyNameLow];

                return GetPropertyByIndex(filePath, index);

            }

            return null;

        }

        /// <summary>

        /// 初始化属性名的下标

        /// </summary>

        private static void InitPropertyIndex()

        {

            Dictionary<string, int> propertyIndex = new Dictionary<string, int>();

            //获取本代码所在的文件作为临时文件,用于获取属性列表

            string tempFile = System.Reflection.Assembly.GetExecutingAssembly().FullName;

            Dictionary<string, string> allProperty = GetProperties(tempFile);

            if (allProperty != null)

            {

                int index = 0;

                foreach (var item in allProperty.Keys)

                {

                    //属性名统一转换为小写,用于忽略大小写

                    _propertyIndex.Add(item.ToLower(), index);

                    index++;

                }

            }

            _propertyIndex = propertyIndex;

        }

GetPropertyEx

  

propertyIndex用于存储属性名与其下标,用Dictionary是因为_propertyIndex[key]的时间复杂度是O(1)。然后在GetPropertyEx方法中找到属性名对应的下标,直接返回该下标的属性值。InitPropertyIndex方法只会被调用一次。

好了,我们现在通过属性名来获取属性值,在不同系统之间应该不会有问题了吧?

不一定,原因你肯定也想到了,如果是在一个英文windows上,它的属性名里面不会有“尺寸”,对应的应该是“Resolution”之类的(我没有英文版系统,所以只是猜测),也不会有“名称”属性,而是“Name”;

总结一下,

方法名

适用

不适用

GetPropertyByIndex

不同语言的系统

不同版本的系统

GetPropertyEx

不同版本的系统

不同语言的系统

所以,根据你的程序可能的运行环境,选择适合你的方法;

再思考:要能在不同语言不同版本的系统将通用,该怎么办?

C# shell32.dll 的用法的更多相关文章

  1. regsvr32 注册.dll的用法

    Regsvr 32命令是Windows中控件文件(如扩展名为DLL.OCX.CPL的文件)的注册和反注册工具. 命令格式 Regsvr32 [/s] [/n] [/i[:cmdline]] dllna ...

  2. shell32.dll 控制网络

    //禁用 SetNetworkAdapter(False) //启用 SetNetworkAdapter(True) //添加引用system32/shell32.dll private static ...

  3. winform 窗体换皮肤,IrisSkin2.dll的用法

    1. 先把IrisSkin2.dll文件添加到当前项目引用(解决方案资源管理器->当前项目->引用->右键->添加引用,找到IrisSkin2.dll文件.....之后就不用我 ...

  4. WeifenLuo.WinFormsUI.Docking.dll的用法

    基本框架 说明 weiFenLuo.winFormsUI.Docking.dll是开源项目DockPanel Suite的一个类库,可以实现像Visual Studio的窗口停靠.拖拽等功能.Weif ...

  5. Aspose.Cells.dll的用法

    public void OutExcel() { #region WorkbookDesigner designer = new WorkbookDesigner(); Worksheet sheet ...

  6. .OCX、.dll文件注册命令Regsvr32的使用

    1.打开文件,打开需要注册的OCX文件或dll文件,2.然后根据需要进行OCX文件或DLL文件的注册和反注册 DLL.OCX注册方法--文件Regsvr32用法及情况介绍 使用过activex的人都知 ...

  7. 【本地资源路径&&网络资源路径&&正反斜杠在Java中的用法】

    一.概念和用法 左正右反 先来看看转义字符的概念:通过 \ ,?来转变后面字母或符号的含义.意思就是改变字母本身的含义. 以"\"符号为例,JAVA中有很多操作,例如文件操作等,需 ...

  8. SHGetSpecialFolderPath用法

    The SHGetSpecialFolderPath function retrieves the path of a special folder that is identified by its ...

  9. System.Diagnostics.Process.Star的用法

    System.Diagnostics.Process.Start(); 能做什么呢?它主要有以下几个功能: 1.打开某个链接网址(弹窗). 2.定位打开某个文件目录. 3.打开系统特殊文件夹,如“控制 ...

随机推荐

  1. 创建可执行的JAR包并运行

    将一个应用程序制作成可执行的JAR包,通过JAR包来发布应用程序.创建可执行JAR包的关键在于:让java -jar命令知道JAR包中哪个类是主类,java -jar命令可以通过运行该主类来运行程序. ...

  2. [算法模板]FFT-快速傅里叶变换

    [算法模板]FFT-快速傅里叶变换 感谢ZYW聚聚为我们讲解FFT~ 思路 我懒,思路和证明部分直接贴链接: rvalue LSJ-FFT与NTT基础 代码 主要思想是利用了单位根特殊的性质(n次单位 ...

  3. composer中常用命令

    一些常用的composer命令: # 显示所有已经安装的包 composer show # 移除指定的依赖包package_name composer remove package_name # 搜索 ...

  4. 学习强国docker文件用法

    学习强国docker用法 docker文件地址   https://github.com/fuck-xuexiqiangguo/docker 构建  docker  docker build -t D ...

  5. C#斐波那契数列求法(比较阶乘和循环所用时间)

    using System; namespace ConsoleApp3 { class Program { static void Main(string[] args) { Console.Writ ...

  6. .net core 反射的介绍与使用

      1. 概述反射 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象. 反射机制允许程序在执行过程中动态地添加各种功能.   2. Type类的介绍  是BCL(基 ...

  7. Vue的MVVM框架理解

    图示 只上图,请不要怪楼主懒. 这是楼主梳理后画的,因为毕竟自己画的印象深刻,更觉得香啊. 黄线: 表示View->Model, 红线: 表示Model->View 具体代码,请查看Vue ...

  8. dedecmsV5.7 arclist标签同时取出主表和附表里的数据

    {dede:arclist}{/dede:arclist}标签默认取出来的是主表x_archives中的数据,如果要取出附表中的数据,需要满足两个条件: 指定channelid属性(注意:channe ...

  9. IaaS、PaaS、SaaS介绍(非原创)

    文章大纲 一.IaaS.PaaS.SaaS介绍与比较二.参考文章 一.IaaS.PaaS.SaaS介绍与比较 随着云计算.大数据.人工智能等一批新技术的涌入,企业信息化建设速度加快,基于云计算的Iaa ...

  10. redis5.0.4安装配置

    1.下载redis wget http://download.redis.io/releases/redis-5.0.4.tar.gz 2.解压到opt目录 tar -zxvf redis-5.0.4 ...