-
我用
Process.Start
开启进程,其它程序都完全可以,但是这个截图进程就不行。
-
而且完全找不到报错的原因和行号
-
后来在StackOverflow上找到了解决方法
ProcessStartInfo p = new ProcessStartInfo(path);
p.UseShellExecute = false;
p.RedirectStandardError = true;
p.RedirectStandardOutput = true;
Process process = Process.Start(p);
var err = process.StandardError.ReadToEnd();
var msg = process.StandardOutput.ReadToEnd();
- 然后发现是因为截图程序报错了,我代码里面有一个查找文件的方法,但是路径找不到。就报错了,修改以后就可以了。果然还是要多用谷歌啊orz
2000 年 6 月 22 日 不论对 Microsoft 还是对整个 IT 业界都将成为值得纪念的一天
这一天 微软公司正式推出了其下一代计算计划 Microsoft.NET(以下简称.NET)
这项计划将使微软现有的软件在 Web 时代不仅适用于传统的 PC 而且也能够满足目前
呈强劲增长势头的新设备 诸如蜂窝电话以及个人数字助理 Personal Digital Assistant,
PDA 等的需要 微软还计划通过创建新的工具来吸引软件开发人员和合作伙伴对
Microsoft.NET 的认同 并且开发出其他基于 Internet 的服务
那么 你是否想知道 究竟什么是.NET?
请听听微软官员的声音 因特网的革命 从微软的角度来讲 我们就是要
建设一个平台来创建并且支持新一代的应用 我们必须有一套通用系统服务来支
持这样的操作 这种观点就说明 我们还有下一个层次的发展 也就是说因特网下一
步的发展 它将使因特网的作用远远超越展现一个网站
.NET 首先是一个开发平台 它定义了一种公用语言子集 Common Language
Subset CLS ,这是一种为符合其规范的语言与类库之间提供无缝集成的混合语 .NET
统一了编程类库 提供了对下一代网络通信标准 可扩展标记语言 Extensible Markup
终端的支持能力 最为重要的 .NET 将改变因特网的行为方式 软件将变成为服务
与 Microsoft 的其它产品一样 .NET 与 Windows 平台紧密集成 并且与其它微软产品
相比它更进一步 由于其运行库已经与操作系统融合在了一起 从广义上把它称为一
个运行库也不为过
简而言之 .NET 是一种面向网络 支持各种用户终端的开发平台环境 微软的宏
伟目标是让 Microsoft.NET 彻底改变软件的开发方式 发行方式 使用方式等等 并且
不止是针对微软一家 而是面向所有开发商与运营商 .NET 的核心内容之一就是要搭
建第三代因特网平台 这个网络平台将解决网站之间的协同合作问题 从而最大限度
地获取信息 在 .NET 平台上 不同网站之间通过相关的协定联系在一起 网站之间
形成自动交流 协同工作 提供最全面的服务
1.1.2 我们为什么需要.NET
某一天 你出差到外地 在机场租借手机电话 在向该终端插入自己的 IC 卡后
自己的地址簿和计划簿被自动下载 随即它就变成了你个人专用的 PDA 这不是梦境
这是.NET 为我们描绘的一个未来生活的场景
人们的需要总是无法满足 我们不断地问自己 我们还应该有些什么 需求推
动着技术的进步 在二十一世纪 Internet 将成为商业活动的主要场所 B2B B2C 等
电子商务的运作方式 一对一营销的经营概念将网络的服务功能提高到了前所未有的
程度 微软公司在此时提出.NET 有其深远的战略考虑
改革商务模型 微软公司感觉到只靠销售软件包的商务模型没有什么前途 该公
司打算今后将中心转移到可以在网络上使用“服务”型商务 这样 首要的问题就是解
决网络上用来开发并执行“服务”的平台 这就是 Microsoft.NET
提高软件开发生产效率 并且试图使应用软件的发布更为容易 再也不想因为 DLL
版本不同而烦恼 希望不用重新启动电脑就能够安装应用软件
改进用户界面 并能支持多种用户终端 用户界面演进的结果包括两方面的内容
一是完成传统的 PC 界面与基于 XML 的浏览器界面间的过渡 二是对自然语言和语音
识别的支持 从而使用户与各种终端之间的沟通更加透明 真正达到网络互连的 3A
Anywhere Anytime Any device
今天 许多的人时常问 除了上网看新闻 我们究竟还能干什么 这是因为今
天的互联网与旧式的大型计算机的工作模式还有许多相似之处 信息被储存在中央服
务器内 而用户的所有操作都要依靠它们 让不同的网址之间相互传递有意义的信息
或者合作提供更广泛和更深层次的服务 还是一件十分困难的事
现代人时常有一种困惑 感觉到如今生活在技术与机器架构的丛林中 我们在努
力地去适应机器 适应技术 而不是机器和技术适应人类 科技以人为本还只是一个
美好的愿望 这是因为我们还不能将控制信息的权利交给那些需要信息的人们 .NET
开发开销 而.NET Framework 的出现使得一切问题都迎刃而解 实际上 在.NET
Framework 中 所有的编程语言 从相对简单的 JScript 到复杂的 C++语言 一律是等
Framework 框架 是开发人员对编程语言命令集的称呼 .Net 框架的意义就在
于只用统一的命令集支持任何的编程语言 正如微软 Web 服务中心的成组产品经理 John
Montgomery 所说 只需简单地一用 .NET 框架便可消除各种异类框架之间的差异
将它们合并为一个整体 .NET 的作用不仅仅是将开发人员从必须掌握多种框架的束缚
中解脱出来 通过创建跨编程语言的公共 API 集 .NET 框架可提供强大的跨语言继承
性 错误处理和调试功能 现在 开发人员可以自由地选择他们喜欢的编程语言 .NET
平台欢迎所有人的垂顾 ”.NET 将使编程人员梦想的语言互用性变成为近在眼前的现
实 想想看 一个在 Visual Basic VB 中定义的类能够在另一种与它完全不同的语言
环境中使用 调试 甚至继承 这是多么令人兴奋的事情
.NET 框架是.NET 平台的基础架构 其强大功能来自于公共语言运行时 Common
Language Runtime,CLR 将在第二章中进行详细的解释 环境和类库 CLR 和类库 包
括 Windows Forms ADO.NET 和 ASP.NET 紧密结合在一起 提供了不同系统之间
交叉与综合的解决方案和服务 .NET 框架创造了一个完全可操控的 安全的和特性丰
富的应用执行环境 这不但使得应用程序的开发与发布更加简单 并且成就了众多种
类语言间的无缝集成
1.2.2 面向.Net 的全新开发工具 C#
在最近的一段时间里 C 和 C++一直是最有生命力的程序设计语言 这两种语言
为程序员提供了丰富的功能 高度的灵活性和强大的底层控制能力 而这一切都不得
不在效率上作出不同程度的牺牲 如果你使用过包括 C 和 C++在内的多种程序设计语
言 相信你会深刻体会到它们之间的区别 比如与 Visual Basic 相比 Visual C++程序
员为实现同样的功能就要花费更长的开发周期 由于 C 和 C++即为我们带来了高度的
灵活性 又使我们必须要忍受学习的艰苦和开发的长期性 许多 C 和 C++程序员一直
在寻求一种新的语言 以图在开发能力和效率之间取得更好的平衡
今天 人们改进 开发出了许多语言以提高软件生产率 但这些或多或少都以牺
牲 C 和 C++程序员所需要的灵活性为代价 这样的解决方案在程序员身上套上了太多
的枷锁 限制了他们能力的发挥 它们不能很好地与原有的系统兼容 更为令人头痛
的是 它们并不总是与当前的 Web 应用结合得很好
理想的解决方案 是将快速的应用开发与对底层平台所有功能的访问紧密结合在
不但如此 C#还能为 C++程序员提供快捷的开发方式 又没有丢掉 C 和 C++的基
本特征 强大的控制能力 C#与 C 和 C++有着很大程度上的相似性 熟悉 C 和 C++
的开发人员很快就能精通 C#
现它是那样的熟悉 即使你是一位新手 C#也不会给你带来任何其它的麻烦 快速应
用程序开发 Rapid Application Development RAD 的思想与简洁的语法将会使你迅
速成为一名熟练的开发人员
正如前文所述 C#是专门为.NET 应用而开发出的语言 这从根本上保证了 C#
与.NET 框架的完美结合 在.NET 运行库的支持下 .NET 框架的各种优点在 C#中表现
得淋漓尽致 让我们先来看看 C#的一些突出的特点 相信在以后的学习过程中 你将
会深深体会到 # SHARP 的真正含义
简洁的语法
精心地面向对象设计
与 Web 的紧密结合
完整的安全性与错误处理
版本处理技术
灵活性与兼容性
1.3.1 简洁的语法
请原谅 虽然我们一再强调学习本书不需要任何的编程基础 但在这里还不得不
提到 C++
在缺省的情况下 C#的代码在.NET 框架提供的 可操控 环境下运行 不允许直
接地内存操作 它所带来的最大特色是没有了指针 与此相关的 那些在 C++中被疯
狂使用的操作符 例如 -> 和 ., 已经不再出现 C#只支持一个 . 对
C#用真正的关键字换掉了那些把活动模板库 Active Template Library ALT 和
COM 搞 得 乱 糟 糟 的 伪 关 键 字 , 如 OLE_COLOR BOOL VARIANT_BOOL
DISPID_XXXXX 等等 每种 C#类型在.NET 类库中都有了新名字
语法中的冗余是 C++中的常见的问题 比如 const”和 #define 各种各样的字
符类型等等 C#对此进行了简化 只保留了常见的形式 而别的冗余形式从它的语法
结构中被清除了出去
1.3.2 精心地面向对象设计
也许你会说 从 Smaltalk 开始 面向对象的话题就始终缠绕着任何一种现代程序
设计语言 的确 C#具有面向对象的语言所应有的一切特性 封装 继承与多态 这
并不出奇 然而 通过精心地面向对象设计 从高级商业对象到系统级应用 C#是建
造广泛组件的绝对选择
在 C#的类型系统中 每种类型都可以看作一个对象 C#提供了一个叫做装箱
boxing 与拆箱 unboxing 的机制来完成这种操作 而不给使用者带来麻烦 这在
以后的章节中将进行更为详细的介绍
C#只允许单继承 即一个类不会有多个基类 从而避免了类型定义的混乱 在后
面的学习中你很快会发现 C#中没有了全局函数 没有了全局变量 也没有了全局常
数 一切的一切 都必须封装在一个类之中 你的代码将具有更好的可读性 并且减
少了发生命名冲突的可能
整个 C#的类模型是建立在.NET 虚拟对象系统 Visual Object System VOS 的基
础之上 其对象模型是.NET 基础架构的一部分 而不再是其本身的组成成分 在下面
将会谈到 这样做的另一个好处是兼容性
借助于从 VB 中得来的丰富的 RAD 经验 C#具备了良好的开发环境 结合自身强
大的面向对象功能 C#使得开发人员的生产效率得到极大的提高 对于公司而言 软
件开发周期的缩短将能使它们更好地应付网络经济的竞争 在功能与效率的杠杆上人
们终于找到了支点
1.3.3 与 Web 的紧密结合
.NET 中新的应用程序开发模型意味着越来越多的解决方案需要与 Web 标准相统
一 例如超文本标记语言 Hypertext Markup Language HTML 和 XML 由于历史
的原因 现存的一些开发工具不能与 Web 紧密地结合 SOAP 的使用使得 C#克服了这
一缺陷 大规模深层次的分布式开发从此成为可能
由于有了 Web 服务框架的帮助 对程序员来说 网络服务看起来就像是 C#的本地
对象 程序员们能够利用他们已有的面向对象的知识与技巧开发 Web 服务 仅需要使
用简单的 C#语言结构 C#组件将能够方便地为 Web 服务 并允许它们通过 Internet 被
运行在任何操作系统上的任何语言所调用 举个例子 XML 已经成为网络中数据结构
传送的标准 为了提高效率 C#允许直接将 XML 数据映射成为结构 这样就可以有
.NET 运行库提供了代码访问安全特性 它允许管理员和用户根据代码的 ID 来配
置安全等级 在缺省情况下 从 Internet 和 Intranet 下载的代码都不允许访问任何本地
文件和资源 比方说 一个在网络上的共享目录中运行的程序 如果它要访问本地的
一些资源 那么异常将被触发 它将会无情地被异常扔出去 若拷贝到本地硬盘上运
行则一切正常 内存管理中的垃圾收集机制减轻了开发人员对内存管理的负担 .NET
平台提供的垃圾收集器 Garbage Colection GC 将负责资源的释放与对象撤销时的
内存清理工作
变量是类型安全的 C#中不能使用未初始化的变量 对象的成员变量由编译器负
责将其置为零 当局部变量未经初始化而被使用时 编译器将做出提醒 C#不支持不
安全的指向 不能将整数指向引用类型 例如对象 当进行下行指向时 C#将自动验
证指向的有效性 C#中提供了边界检查与溢出检查功能
1.3.5 版本处理技术
C#提供内置的版本支持来减少开发费用 使用 C#将会使开发人员更加轻易地开发
和维护各种商业应用
升级软件系统中的组件 模块 是一件容易产生错误的工作 在代码修改过程中
可能对现存的软件产生影响 很有可能导致程序的崩溃 为了帮助开发人员处理这些
问题 C#在语言中内置了版本控制功能 例如 函数重载必须被显式地声明 而不会
像在 C++或 Java 中经常发生的那样不经意地被进行 这可以防止代码级错误和保留版
本化的特性 另一个相关的特性是接口和接口继承的支持 这些特性可以保证复杂的
软件可以被方便地开发和升级
1.3.6 灵活性和兼容性
在简化语法的同时 C#并没有失去灵活性 尽管它不是一种无限制的语言 比如
它不能用来开发硬件驱动程序 在默认的状态下没有指针等等 但是 在学习过程中
你将发现 它仍然是那样的灵巧
如果需要 C#允许你将某些类或者类的某些方法声明为非安全的 这样一来 你
正是由于其灵活性 C#允许与 C 风格的需要传递指针型参数的 API 进行交互操作
DLL 的任何入口点都可以在程序中进行访问 C#遵守.NET 公用语言规范 Common
Language Specification CLS 从而保证了 C#组件与其它语言组件间的互操作性 元
数据 Metadata 概念的引入既保证了兼容性 又实现了类型安全
许多强大的功能均来自.NET 平台的支持 因此 要想真正掌握 C#首先必须了解.NET
本章将向你介绍 C#的运行环境 重点放在.NET 公用语言运行时环境与公用语言规范
上 最后介绍了.NET 的开发工具
一种编译语言相同 而即使相同的数据类型在不同的语言环境中表示的意义也存在差
别 例如 同样是整数类型 在 MSSQL 中的长度是 32 位 而在 VB 中却是 16 位 至
于日期时间与字符串类型在这方面的区别就更加明显了
VOS 的建立就是为了改变这种状况 它既支持过程性语言也支持面向对象的语言
同时提供了一个类型丰富的系统来容纳它所支持的各种语言的特性 它在最大程度上
屏蔽了不同语言类型系统间的转换 使程序员能够随心所欲地选择自己喜欢的语言 当
然 这种语言必须支持.NET 应用 从事开发 保证了不同语言间的集成
对于过程性语言 它描述了值的类型并指定了类型的所有值必须遵守的规则 在
面向对象的语言方面 它统一了不同编程语言的对象模型 每一个对象在 VOS 中都被
唯一标识以与其它对象相区别
公用语言规范 Common Language Specification CLS 是 CLR 定义的语言特性
集合 主要用来解决互操作问题 如果一个类库遵守 CLS 那么同样遵守 CLS 规范的
其它编程语言将能够使用它的外部可见项 详细的内容见本章第二节
2.1.4 虚拟执行系统
虚拟执行系统 Visual Execution System VES 是 VOS 的实现 它用来驱动运行
环境 元数据的生成与使用 公用语言规范的满足性检查以及应用程序执行过程中的
内存管理均由它来完成 具体说来 VES 主要完成以下功能
装入中间代码
使用 JIT 将中间代码转换为本地码
装入元数据
代码管理服务 包括垃圾收集器和异常处理
定制与调试服务
线程和环境管理
当你完成并编译你的代码时 编译器将它转换为微软中间语言 Microsoft
Intermediate Language MSIL 同时产生元数据 当你要执行你的代码时 这种中间
语言被即时 Just In Time JIT 编译器编译成为本地代码 如果安全策略需要的代码
是类型安全的 通常情况下都是如此 JIT 编译器将在编译进程中对中间语言进行
类型检查 一旦失败 在代码执行中将会触发异常
2.2.3 CLR 的突出特色
跨语言集成的能力
CLR 包含了一个丰富的语言特性集 保证了它与各种程序设计语言的兼容性 这
一特性集即公用语言规范 稍后将对其进行详细说明
内存管理自动化
在执行过程中管理应用程序的资源是一项单调而困难的工作 它会将你的注意力
从你本应解决的问题中引开 而垃圾收集机制完全解决了程序员在编程过程中头痛的
问题 跟踪内存的使用 并知道何时将它们释放
在面向对象的环境中 每种类型都标识了对你的应用有用的某种资源 为了使用
这些资源 你需要为类型分配内存 在应用中 访问一种资源要通过以下步骤
1 为类型分配内存
2 初始化内存 设置资源的初始状态并使其可用
3 通过访问该类型的实例成员来访问资源
4 卸下将被清除的资源状态
5 释放内存
这一看似简单的过程在实际的编程中是产生程序错误的主要来源之一 更可怕的
是 内存中的错误往往导致不可预见的结果 如果你有过编程的经验 想想看 有多
少次你的程序因为内存访问错误而崩溃
CLR 要求所有的资源从可操控的堆 注 在此指一种内存结构 中分配 当一个
进程被初始化后 CLR 保留了一个未被分配的地址空间 这一区域叫做可操控堆 在
堆中保持了指向下一个将被分配给对象的堆地址的指针 NEXT 初始状态下 该指
针是保留地址空间的基地址 一个应用使用新的操作产生对象 此操作首先检查新对
象需要字节的大小是否会超出保留空间 如果对象大小合适 指向下一个地址的指针
将指向堆中的这个对象 该对象的构造器被调用 新的操作返回对象的地址
当一个应用请求建立一个对象时 地址空间可能不够大 堆将发现这一点 通过
将新对象的大小与 NEXT 指针相加 并与堆的大小进行比较 这时垃圾收集器就将被
调用 在这里 CLR 引入了 代 的概念 代 指堆中对象产生的先后 这样 垃圾
收集器在将发生溢出时回收属于特定的 代 的对象 而不是回收堆中的所有对象
6 即时编译
在各种语言的编译器对源代码进行编译之后 在 CLR 环境中产生的是中间代码 出
于兼容性与跨语言集成的考虑 其内容虽然有效 但在转化为本地代码之前它本身是
不可执行的 这就是 JIT 编译器需要完成的工作
这里需要说明一个问题 为什么要即时编译 而不是一次性的将中间代码文件进
行编译 答案很简单 原因在于效率 在大型的应用中 你很少会用到程序的全部功
能 这种边执行边编译的措施比一次性的完全编译效率更高
在 Windows 平台中 CLR 带有三个不同的 JIT 编译器
7 缺省的编译器 主编译器 由它进行数据流分析并输出经过优化的本地代
码 所有的中间代码指令均可被它处理
8 PREJIT 它建立在主 JIT 编译器之上 其运行方式更像一个传统的编译器
每当一个.NET 组件被安装时它就运行
9 ECONOJIT 在并不充分优化的前提下 它能够快速完成 IL 代码到本地码的
转换 编译速度与运行速度都很快
为了配合编译器的工作 在.NET SDK 的安装路径下的/bin 目录中有一个负责管理
JIT 的应用程序 jitman.exe 具体的使用参见联机帮助
10 解决版本与发布问题
在当前以组件为基础的系统中 开发人员和用户对于软件版本和发布中存在的问
题已经十分熟悉了 当我们安装一个新的应用之后 我们很可能发现原本正常的某个
应用程序奇怪地停止了工作 绝大多数开发人员将时间花在了确保所有注册表入口的
一致性 以便激活 COM 类上 这就是所谓的 DLL 地狱
.NET 平台通过使用集合来解决这一问题 在这里 集合 是一个专有名词 指
类型与资源的发布单元 在很大程度上它等同于今天的 DLL 正像.NET 用元数据描述
类型一样 它也用元数据描述包含类型的集合 通常说来 集合由四个部分组成 集
合的元数据 集合的内部清单 元数据描述的类型 实现类型的中间语言代码和一组
资源 在一个集合中 以上四个部分并不是都必须存在 但是 集合中必须包含类型
或资源 这样集合才有意义
在.NET 中一个基本的设计方针是使用孤立的组件 一个孤立的集合的含义是指一
个集合只能被一个应用所访问 在一台机器上 它不被多个应用共享 也不会受其它
应用程序对系统的更改的影响 孤立 赋予了开发人员在自己的程序中对代码的完全
过程中涉及的数据类型和语言特性对所有的语言来说是公共的 为了这个目的 公用
运行时环境标识了一组语言特征的集合 称为公用语言规范 CLS 如果你的组件在
应用程序接口 Application Program Interface 中仅使用 CLS 的特征语言 包括子类
那么该组件能够被任何支持CLS的语言所编译的组件访问 所有支持CLS并仅使用CLS
中的语言特征的组件被称为符合 CLS 的组件
设计公用语言规范时遇到的一个最主要的挑战是选择适当的语言特性子集的大
小 它应具有完全的表达能力 又应足够小 使得所有的语言能够容纳它 由于 CLS
是关于语言互用性的规范 它的规则仅应用于外部可见的条目中 CLS 假设语言间的
互操作性仅在语言集合的边界发生交叉时才是重要的 也就是说 在单一的语言集中
对于编程技术的使用没有任何限制 CLS 的规则仅作用于在定义它们的语言集合之外
仍然可见的项上 这样就大大缩小了 CLS 的范围 减轻了系统的负担
在 CLS 中是用 System.CLSCompliantAtribute 类来标识一个集合或者类是否是符合
CLS 规范的 在 System.CLSCompliantAtribute 的构造器中有一个 Boolean 型的返回值
代表了与之相关联的项是否符合 CLS 规范
或 MSIL 格式的文件转换为带有内容清单的集合
3. Windows Forms ActiveX Control Importer (aximp.exe) 完成 COM 类库中类型定
义的转换 使 ActiveX 控件能够在 Windows 窗口控件上使用
4. Code Access Security Policy Utility (caspol.exe) 在用户与机器水平上修改安全策
<> page begin====================
5. Software Publisher Certificate Test Utility (Cert2spc.exe) 用于从 X.509 证书中生
成软件出版证明书 SPC
6. Certificate Manager Utility (certmgr.exe) 管理证书 证书信任列表和证书回收列
7. Certificate Verification Utility (chktrust.exe) 检查证书签名的合法性
8. Runtime Debugger (cordbg.exe) 运行时调试器 是一个命令行程序 帮助开发
人员发现和调试基于 CLR 的应用程序中的错误
9. Global Assembly Cache Utility (gacutil.exe) 允许你浏览与操纵全局集合缓存中
内容的命令行程序
10. MSIL Assembler (ilasm.exe) MSIL 汇编程序 协助设计与实现 MSIL 生成器的
11. MSIL Disassembler (ildasm.exe) MSIL 反汇编程序 与 ilasm.exe 共同使用 将
由 MSIL 代码产生的 Portable Executable 文件转换为文本文件
12. Instaler Utility (instalutil.exe) 用来安装与卸载服务资源
13. License Compiler (lc.exe) 产生可包含在可执行二进制文件中的二进制资源文
14. Certificate Creation Utility (makecert.exe) 生成 X.509 证书与用于数字签名的公
用与私有密钥
15. Permissions View Utility(permview.exe) 通过一个集合浏览许可集的工具
16. Peverify Utility(peverify.exe) 检查中间语言与元数据是否符合类型安全认证要
17. Assembly Registration Tool(RegAsm.exe) 读取集合中的元数据并加上必要注册
表入口信息 使得 COM 客户透明地建立 CLR 的类
18. Services Registration Tool (RegSvcs.exe) 服务注册工具 它完成执行以下功能
装载与注册一个集合 为现有的 COM+1.0 应用生成 注册与安装类库
19. Resource File Generator Utility(ResGen.exe) 资源文件生成器 用来将文本文件
和 XML 格式的资源文件转换为 CLR 的二进制文件
20. Secutil Utility(SecUtil.exe) 使得从集合中抽取的安全信息更加容易
21. Set Registry Utility(setreg.exe) 改变注册表中公开密钥密码系统的设置
22. Assembly Cache Viewer(shfusion.dl) 允许你使用 Windows 浏览器察看与操作
全局集合缓存中的内容
23. File Signing Utility(signcode.exe) 为 PE (portable executable)文件做标记 赋予
程序员在组件安全约束的基础上对安全性有更多的控制权
24. Shared Name Utility(Sn.exe) 帮助程序员以共享名称建立集合
25. Soapsuds Utility(SoapSuds.exe) 使用远程技术帮助你编译与 Web 服务相通信的
26. Isolated Storage Utility(storeadm.exe) 一种用来管理隔离存储区的命令行工具
27. Type Library Exporter(TlbExp.exe) 命令行程序 生成由集合名称指示的包含集
合中公共类型定义的类库
<> page begin====================
28. Type Library Importer (TlbImp.exe) 将 COM 类库中的类型定义转换为在 CLR
中与元数据格式一致的类型定义
29. Web Service Utility(WebServiceUtil.exe) 帮助建立 ASP.NET Web 服务与客户
30. Windows Forms Class Viewer(wincv.exe) 能够在某种查找模式下快速查找类或
者类序列的信息
31. Windows Forms Designer Test Container(windes.exe) 允许开发人员测试开发出
的视窗窗体控件在设计时的行为
32. XML Schema Definition Tool(xsd.exe) XML 计划定义工具
可以这么说 与用户没有任何交互的应用程序根本没有任何用处 病毒和黑客当
然除外 然而即使是病毒程序的作者 也常常喜欢在自己得逞之后炫耀一番 学习任
何一门语言 绝大多数情况下人们都是从输入输出开始的
第一个程序总是非常简单的 我们让用户通过键盘输入自己的名字 然后程序在
屏幕上打印一条欢迎信息 程序的代码是这样的
程序 序清 清单单 3-1
using System;
class Welcome
static void Main() {
Console.WriteLine("Please enter your name:");
Console.ReadLine();
Console.WriteLine("Welcome to you!");
您可以在任意一种编辑软件中完成上述代码的编写 然后把文件存盘 文件名叫
做 Welcome.cs 典型的 C#源文件通常都是以 .cs 作为文件的扩展名
using System 表示导入名字空间 高级语言总是依赖于许多系统预定义的元素 如果
您是 C 或 C++的程序员 那么您一定对使用#include 之类的语句来导入其它 C 或 C++
源文件再熟悉不过了 C#中的含义与此类似 用于导入预定义的元素 这样在自己的
程序中就可以自由地使用这些元素
如果没有导入名字空间的话 我们该怎么办呢 程序还能保持正确吗 答案是肯
定的 那样的话 我们就必须把代码改写成下面的样子
程序 序清 清单 单 3-2
class Welcome
static void Main() {
System.Console.WriteLine("Please enter your name:");
System.Console.ReadLine();
System.Console.WriteLine("Welcome to you!");
也就是说 在每个 Console 前加上一个前缀 System. 这个小原点 . 表示 Console
是作为 System 的成员而存在的 C#中抛弃了 C 和 C++中繁杂且极易出错的操作符像 :
和 -> 等 C#中的复合名字一律通过 . 来连接
System 是.Net 平台框架提供的最基本的名字空间之一 有关名字空间的详细使用
方法我们将放在第十七章中详细介绍 在这里 只要我们学会怎样导入名字空间就足
3.2.2 类和类的方法
让我们从写第一个程序时就记住 每个东西都必须属于一个类 如果您是 C 或 C++
的程序员 请暂时忘掉那些全局变量
在程序的第二行 class Welcome 声明了一个类 类的名字叫做 Welcome 这个程
序为我们所作的事情就是依靠它来完成的
和 C C++中一样 源代码块被包含在一对大括号 { 和 } 中 每一个右括号
} 总是和它前面离它最近的一个左括号 { 相配套 如果左括号 { 和右括号 }
没有全部配套 那程序就是一个错误的程序
static void Main()表示类 Welcome 中的一个方法 方法总是为我们完成某件工作的
注意 在 C#程序中 程序的执行总是从 Main()方法开始的 一个程序中不允许出
上面的代码中 类 Console 为我们展现了两个最基本的方法 WriteLine 和 ReadLine
Console.ReadLine 表示接受输入设备输入 Console. WriteLine 则用于在输出设备上输
我们再为读者介绍 Console 中用于输入输出的另两个方法 Read 和 Write 它们和
ReadLine 与 WriteLine 的不同之处在于 ReadLine 和 WriteLine 执行时相当在显示时多
加了一个回车键 而使用 Read 和 Write 时则光标不会自动转移到下一行
让我们再对例子程序进行扩展 使得用户的输入对输出产生作用
程序序清 清单 单 3-3
using System;
class Welcome
static void Main() {
Console.WriteLine("Please enter your name:");
string name = Console.ReadLine();
Console.WriteLine("Welcome to you,{0}!",name);
我们用到了 string name = Console.ReadLine()这条语句 其中 string name 表示声明一
个字符串类型的变量 name 系统定义的 Console 类提供的方法 ReadLine()的返回值类型
为 string 所以 这句话表示从输入设备读取一个字符串 并把读取的值赋予变量 name
再来看一下程序的最后一条输出语句
Console.WriteLine("Welcome to you,{0}!",name);
这条语句表示在屏幕上对输出的字符串进行格式化 其中表示用方法的第二个参
数来替代格式化后字符串相应的位置 对字符串进行格式化的参数可以是一个字符串
也可以是一个字符 或者是一个整数 等等 采用这种方式最多可以格式化三个变量
int x = 3;
string name1 = “Mike”;
和绝大多数编程语言一样 C#提供了字符串类型 string 它与 C 中的 MFC 为我们
提供的类十分类似 C#中的 string 类型是一个引用类型 引用类型在第四章中我们有
详细说明 为标准字符集 利用 string 可以方便地对字符串进行连接 截断等操作
string s = “Good” + “Morning”;
char x = s[3];
例子演示了字符串 s 由两个字符串 Good 和 Morning 相加得到 字符串还可
以通过下标进行索引 得到一个字符 上面的例子中字符 x 的值为 o
所以 源程序 3-4 和源程序 3-3 的作用没什么区别
程序 序清 清单 单 3-4
using System;
class Welcome
static void Main() {
Console.WriteLine("Please enter your name:");
string message = “Welcome to you “ + Console.ReadLine();
Console.WriteLine(mesage);
如果您的电脑上安装了 Visual Studio .Net 则可以在集成开发环境 Integrated
Developer Environment IDE 中直接选择快捷键或菜单命令 编译并执行源文件
如果您不具备这个条件 那么您至少需要安装 Microsoft .Net Framework SDK 这
样才能够不妨碍您在本书中继续学习 C#语言 实际上 .Net 平台内置了 C#的编译器
下面让我们使用这个微软提供的命令行编译器对我们的程序进行编译
启动一个命令行提示符 在屏幕上输入一行命令
csc welcome.cs
编译这个过程 而在 C 和 C++中要经过编译和链接两个阶段 换而言之 C#源文件并不
被编译为目标文件 .obj 而是直接生成可执行文件 .exe 或动态链接库 .dll
C#编译器中不需要包含链接器
我们可以灵活地使用 .Net 平台提供的命令行编译器的不同选项 选择不同的编译
方式 从而灵活地对编译进行控制
例如 如果我们希望对源文件 Welcome.cs 进行编译 生成名为 MyWelcome.exe 的
可执行文件 我们可以采用这样的命令
csc/out: MyWelcome.exe Welcome.cs
如果我们并不需要一个可执行文件 而仅仅是希望简单地检查源文件中是否存在
语法错误 则命令可以写成
csc/nooutput: Welcome.cs
如果不知道各个选项的具体含义 可以通过求助来获得
csc/?
为方便读者 我们在表 3-1 中按字母排序的顺序列出了命令行编译器 csc 常用的参
数及其用途 更详细的信息请参阅 C#联机帮助文档
表 3-1 命令行编译器选项
选项 作用
@ 指定响应文件
/? 列出编译命令选项
/addmodule 指定一个或多个模块作为装配的一部分
/baseaddress 指定载入动态链接库的首选地址
/bugreport 生成一个报告文件 其中包含程序 Bug 的详细信息
/checked 指定算术运算的溢出是否会导致程序在运行时抛出一个异常
/codepage 指定编译的所有源文件所使用的代码页
/debug 给出调试信息
/define 定义预处理程序的符号
/doc 由文件注释生成 XML 文件
/fulpaths 指定输出的绝对路径
/help 列出编译命令选项
/incremental 允许对源文件进行递增式编译
/linkresource 在装配时链接指定的 NET 资源
注释的方式和 ++没有区别 每一行中双斜杠 后面的内容 以及在
分割符 和 之间的内容都将被编译器忽略
这样 我们就可以采用 进行单行注释 采用分割符 和
进行多行注释 让我们对 Welcome 程序加上注释
程序序清 清单 单 3-5
源文件 welcome.cs
/ 说明 这里是我的第一个
上面的注释似乎有些小题大做 但它毕竟说明了 中注释的使用方法
下面是对 程序进行注释时要注意的两个问题
首先 避免在 之后的单行注解中使用反斜杠符号 \ 因为反斜杠符号 \
在 中是一个续行符 这样做往往会导致你所不希望的结果出现 例如 当你写了
类似于下面的代码
Console.WriteLine(“The result is:{0}” , / \
150 );
在编译这段代码时 表示逻辑上同一行剩余的所有文字被作为注释看待
而续行符 \ 则将这一行同下一行连接起来 那么第二行也被作为注释的一部分 这
时编译器找不到与第一行的左括号 相匹配的右括号 因此编译出错
其次 分割符 和 之间的注释不能有嵌套注释 这是因为
编译器从遇到第一个分割符 开始 将忽略下一个 直到遇上下一个与
之匹配的分割符 才认为注释结束 这样编译器就会对多余的 报告
C# 应用程序开发时,修改程序代码后,调试运行程序 莫名其妙弹出这个报错。
百度找解药呀,,找了好多方法,,都是 " 项目--->配置属性---->链接器---->清单文件--->生成清单-->设置为"否" "
然后这个并没有用。并不能解决我得!!!!!!!!!!!!
百思不得其姐,只是修改了几个函数内的代码,并没有修改解决方案任何属性配置什么的
,不可能会导致这样的问题哟。
经过几个小时的折腾,,终于找到答案。。。
但凡以后看到这种提示...
使用 CreateProcess 函数创建进程(调用外部程序)算是很常用的操作了,最近在工作中却遇到一个少见的怪现象,经常使用的一段代码(调用外部程序并等待其结束,主要就使用了 CreateProcess 函数),在少数某些机器上会失败。经调查分析,发现正是 CreateProcess 调用失败,GetLastError 返回 0x05 错误(ERROR_ACCESS_DENIED)
今天还是继续说说C#调用系统Api启动外部程序的方法,今天要说的是CreateProcess这个Api函数,相比前两篇文章(一、二)中所说的Api,CreateProcess参数要更复杂一些,但使用起来,要更灵活。1.
using System.Runtime.InteropServices;
2. CreateProcess中用到了几个结构体类型,先声明他们:
[Syste...