P/Invoke .NET调用win32API
项目:无线无源测温软件系统
项目中,用到使用P/Invoke在.NET调用win32API,实现对ini配置文件的读写功能!因为有一些配置信息需要保存下来,以便在下一次启动程序完成初始化,这实际上是一种类持久化。将
一些信息写入INI文件(initialization file)中,可完成简单的持久化支持。
Windows提供了API接口用于操作INI文件,其支持的INI文件格式一般如下:
===============================
[Section1]
Key11=value11
Key12=value12
[Section2]
Key21=value21
Key22=value22
...
[SectionN]
KeyN1=valueN1
KeyN2=valueN2
===============================
一般一个INI文件可有N个节,每节可有n个键名及值对应,每个键名及其值以等式形式占一行。
一般键的名称可任取,不过建议用有意义的字符及词构成。值一般可为整数和字符串,其它类型要进行转换。
常见的系统配置文件:
C:/boot.ini
C:/WINDOWS/win.ini
C:/WINDOWS/system.ini
C:/WINDOWS/desktop.ini
C:/WINDOWS/Resources/Themes/Windows Classic.theme
注意,字符串存贮在INI文件中时没有引号;key和value之间的等号前后不容空格;注释以分号“;”开头。
但是令人遗憾的是C#所使用的.NET框架下的公共类库并没有提供直接操作INI文件的类,所以唯一比较理想的方法就是调用API函数。
然后,.Net框架下的类库是基于托管代码的,而API函数是基于非托管代码的,(在运行库的控制下执行的代码称作托管代码。相反,在运行库之外运行的代码称作非托管代码。)如何实现托管代码与非托管代码之间的操作呢?.Net框架的System.Runtime.InteropServices命名空间下提供各种各样支持COM interop及平台调用服务的成员,
在受控代码与非受控代码进行交互时会产生一个事务(transition) ,这通常发生在使用平台调用服务(Platform Invocation Services),即P/Invoke
平台调用是一种服务,它使托管代码能够调用 DLL 中实现的非托管函数,如调用系统的 API 或与 COM 对象打交道,通过 System.Runtime.InteropServices 命名空间
为了从托管代码中调用非托管的DLL中函数,你要创建一个P/Invoke包装(Wrapper)。一个P/Invoke包装是一个.net兼 容的方法声明,用来创建P/Invoke包装的语法与创建托管方法的声明语法本质上是一样的。唯一不同是P/Invoke包装不包含函数体,而只有方法 名、返回值类型和参数信息。并且,P/Invoke包装使用了DllImport属性。这个属性是用来定位包含有目标函数的非托管的DLL。
其中最重要的属性之一DllImportAttribute可以用来定义用于访问非托管API的平台调用方法,它提供了对从非托管DLL导出的函数进行调用所必需的信息。下面就来看一下如何实现C#与API函数的互操作。
读操作:
[DllImport("kernel32")]
private static extern int GetPrivateProfileString(string section, string key, string defVal, StringBuilder retVal, int size, string filePath);
section:要读取的段落名
key: 要读取的键
defVal: 读取异常的情况下的缺省值
retVal: key所对应的值,如果该key不存在则返回空值
size: 值允许的大小
filePath: INI文件的完整路径和文件名
写操作:
private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
section: 要写入的段落名
key: 要写入的键,如果该key存在则覆盖写入
val: key所对应的值
filePath: INI文件的完整路径和文件名
例如:
MessageBox在win32的头文件中的声明:
int WINAPI MessageBoxA(HWnd,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);
那么我们要在C#中调用这个MessageBox时要这样声明:
using System.Runtime.InteropServices;
public class Win32 {
[DllImport("user32.dll")]
public static extern int MessageBox(int hWnd, String text,
String caption, uint type);
}
然后可以用常规的.net方法去调用这个MessageBox:
public class HelloWorld {
public static void Main() {
Win32.MessageBox(0, "Hello World", "Platform Invoke Sample", 0);
}
}
使用 P/Invoke:包括三个主要步骤:声明、调用,以及错误处理
P/Invoke .NET调用win32API的更多相关文章
- AutoCAD.NET 不使用P/Invoke方式调用acad.exe或accore.dll中的接口(如acedCommand、acedPostCommand等)
使用C#进行AutoCAD二次开发,有时候由于C#接口不够完善,或者低版本AutoCAD中的接口缺少,有些工作不能直接通过C#接口来实现,所以需要通过P/Invoke的方式调用AutoCAD的其他DL ...
- Java 反射 Method的invoke回调调用任意方法
Java 反射 Method的invoke回调调用任意方法 @author ixenos 关键子:Method.Field.invoke方法指针/函数指针.回调函数 invoke回调流程示例 0.由C ...
- .netcore在linux下使用P/invoke方式调用linux动态库
http://www.mamicode.com/info-detail-2358309.html .netcore下已经实现了通过p/invoke方式调用linux的动态链接库(*.so)文件 1 ...
- WPF 精修篇 调用Win32Api
原文:WPF 精修篇 调用Win32Api 栗子是 调用WIn32API 让窗口最前 后台代码 [DllImport("user32.dll")] private static e ...
- BackGroundWorker组件使用、Winform控件的Invoke安全调用
BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作. 可以通过编程方式创建 BackgroundWorker,也可以将它从"工具 ...
- C#调用Win32API
Win32API.cs using System;using System.Drawing;using System.Runtime.InteropServices;using Lordal.Wi ...
- c++ 使用vs2010调用 win32api
以前读书时都是用vc6.0.后来学c#用vs.装系统只装了vs2010.今天用vs2010写c++程序.发现有点陌生.就总结下,免得以后忘记. 首先用vs2010选择c++语言.新建一个win32控制 ...
- qt下调用win32api 修改分辨率
在头文件中添加 #include <window.h> DEVMODE DevMode; EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, ...
- 天灵灵,地灵灵,但愿这个一定灵!!!python调用win32api,启动应用程序窗口
这个是逼到没办法,C#那一套,一点基本没有. 还好,网上找到例程,可以指定帐户启动进程,但愿可以摆脱WIN SERVICE启动产生的SESSION 0 隔离问题. 因为这个问题,以SERVICE启动的 ...
随机推荐
- mysql 启动 导入sql文件
mysql mysqld.exe mysqld.exe 是mysql的服务器进程,只有先启动这个进程才能连接服务器 dos下进入mysql文件目录下的bin目录,输入mysql -u root -p ...
- cf.VK CUP 2015.B.Mean Requests
Mean Requests time limit per test 4 seconds memory limit per test 256 megabytes input standard input ...
- Integer Inquiry
Integer Inquiry Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Sub ...
- Python文件基础
===========Python文件基础========= 写,先写在了IO buffer了,所以要及时保存 关闭.关闭会自动保存. file.close() 读取全部文件内容用read,读取一行用 ...
- java笔记--策略模式和简单工厂模式
策略模式: --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3884781.html "谢谢-- 为什么使用:策略模式主要用于 ...
- 搭建openfire Android 客户端学习和开发【二】spark源码导入eclipse
首先声明下 这是我在eoe上转载的 写的很好就摘抄了... 第一步 下载源码 svn下载,下载地址:spark:http://svn.igniterealtime.org/svn/repos/spar ...
- 5 个最受人喜爱的开源 Django 包
导读 Django 围绕“可重用应用”的思想建立:自包含的包提供了可重复使用的特性.你可以将这些可重用应用组装起来,在加上适用于你的网站的特定代码,来搭建你自己的网站.Django 具有一个丰富多样的 ...
- 添加删除一个controller
(文章是从我的个人主页上粘贴过来的,大家也可以访问我的主页 www.iwangzheng.com) rails generate controller Users rails destroy cont ...
- Quartz作业调度框架
Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度.本 ...
- 【转】 JSONObject使用方法
随笔- 46 文章- 0 评论- 132 JSONObject简介 本节摘要:之前对JSON做了一次简单的介 绍,并把JSON和XML做了一个简单的比较:那么,我就在想,如果是一个json格式的字 ...