C# SetupCopyOEMInf安装驱动并返回DestinationInfFileNameComponent
最近用C#写安装usb驱动,必须得调用API SetupCopyOEMInf:
BOOL WINAPI SetupCopyOEMInf(
_In_ PCTSTR SourceInfFileName,
_In_ PCTSTR OEMSourceMediaLocation,
_In_ DWORD OEMSourceMediaType,
_In_ DWORD CopyStyle,
_Out_opt_ PTSTR DestinationInfFileName,
_In_ DWORD DestinationInfFileNameSize,
_Out_opt_ PDWORD RequiredSize,
_Out_opt_ PTSTR DestinationInfFileNameComponent
);
于是在C#里这么写了:
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupCopyOEMInf(
string SourceInfFileName,
string OEMSourceMediaLocation,
OemSourceMediaType OEMSourceMediaType,
OemCopyStyle CopyStyle,
out string DestinationInfFileName,
int DestinationInfFileNameSize,
int RequiredSize,
out string DestinationInfFileNameComponent
);
其中DestinationInfFileName代表驱动成功安装后,inf文件在C:\Windows\inf目录下的绝对路径,这个inf文件名字和原inf文件不一样,但是内容是一模一样的,不知道为啥inf驱动安装成功后会把inf文件换一个名字然后copy到C:\Windows\inf目录下?有高人解答下吗?
DestinationInfFileNameComponent代表copy到C:\Windows\inf目录下的那个inf的名字,这个很有用,调用SetupUninstallOEMInf卸载驱动的时候要用到这个名字。
然后我在C#中这么调用SetupCopyOEMInf:
unsafe
{
success = SetupCopyOEMInf(infPath, "", OemSourceMediaType.SPOST_PATH, OemCopyStyle.SP_COPY_NEWER, out destinationInfFileName, ,
, out destinationInfFileNameComponent);
}
260是文件目录的最大长度,查看log,C:\Windows\inf\setupapi.dev.log,可以成功安装,success为true,但是接下来的问题困扰了我好久,destinationInfFileNameComponent和destinationInfFileName始终都没有值,按照https://msdn.microsoft.com/en-us/library/aa376990.aspx上的说话,成功执行后会返回这俩值,destinationInfFileNameComponent是调用SetupUninstallOEMInf卸载驱动的必传参数,没有值就无法卸载了,google了半天没有解决,最后看别人用C++写的SetupCopyOEMInf,destinationInfFileName传的是一个长度为260的TCHAR数组,于是我把C#的SetupCopyOEMInf原型改为:
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupCopyOEMInf(
string SourceInfFileName,
string OEMSourceMediaLocation,
OemSourceMediaType OEMSourceMediaType,
OemCopyStyle CopyStyle,
out char[] DestinationInfFileName,
int DestinationInfFileNameSize,
int RequiredSize,
out string DestinationInfFileNameComponent
);
然后把destinationInfFileName声明为一个260长度的char数组,但是调用会报executionexception的异常。后来把原型参数char[] destinationInfFileName前面的out去掉,destinationInfFileNameComponent的值终于正确得到了!!!!!!!!
但是destinationInfFileName依然无法得到,好歹有了一个,终于可以做卸载了,具体为什么可以了也不太清楚,为什么PTSTR DestinationInfFileName传递C#的string不对?传递char数组才可以,但是无法使用out,估计destinationInfFileNameComponent是在destinationInfFileName的基础上得到的,所以传递string类型的destinationInfFileNameComponent是可以的吧,糊涂了!
完美的解决方法:
原型:
[DllImport("setupapi.dll", SetLastError = true)]
private static extern bool SetupCopyOEMInf(
string SourceInfFileName,
string OEMSourceMediaLocation,
OemSourceMediaType OEMSourceMediaType,
OemCopyStyle CopyStyle,
StringBuilder DestinationInfFileName,
int DestinationInfFileNameSize,
int RequiredSize,
out string DestinationInfFileNameComponent
);
调用:
string msg = "";
int size = ;
StringBuilder destinationInfFileName_builder = new StringBuilder();
unsafe
{
success = SetupCopyOEMInf(infPath, "", OemSourceMediaType.SPOST_PATH, OemCopyStyle.SP_COPY_NEWER, destinationInfFileName_builder, destinationInfFileName_builder.Capacity,
,out destinationInfFileNameComponent);
}
if (!success)
{
var errorCode = Marshal.GetLastWin32Error();
var errorString = new Win32Exception(errorCode).Message;
msg = errorString;
}
把destinationInfFileName设成一个有260个字符长的空stringbuilder,stringbuilder是按引用传值,所以不需要添加out或者ref了,但是destinationInfFileNameComponent必须是out string,设成stringbuilder会是乱码。
这样destinationInfFileNameComponent和destinationInfFileName都能正确得到了!这样是不是可以猜测,C#调用WINAPI,如果函数原型参数是_Out_opt_ PTSTR,并且这个PTSTR要有长度输入,在C#中就可以声明成StringBuilder?
参考:
http://www.pinvoke.net/default.aspx/setupapi.SetupCopyOEMInf
https://msdn.microsoft.com/en-us/library/aa376990.aspx
http://stackoverflow.com/questions/18404660/how-to-use-setupcopyoeminf-during-installer
C# SetupCopyOEMInf安装驱动并返回DestinationInfFileNameComponent的更多相关文章
- 用Setup系列函数完成驱动卸载安装[驱动安装卸载程序]
// InstallWDFDriver.cpp : Defines the entry point for the console application. // #include "std ...
- monkeyrunner之电脑安装驱动(五)
在Monkeyrunner做自动化测试时,可以使用模拟器,当然也可以选择用真机.不过,要想通过电脑来安装软件,操作手机,则必须先安装手机驱动,而且一般手机连接电脑之后,电脑会自动开始下载驱动.不过也经 ...
- JZ2440开发板学习 1. 刚接触开发板, 安装驱动
一. jtag和串口驱动 1. 驱动下载 http://pan.baidu.com/s/1pJkAHJH 2. 驱动安装 禁用win10的驱动数字签名 http://www.100ask.org/bb ...
- 子进程 已安装 pre-removal 脚本 返回了错误号 1或2 与 子进程 已安装 post-installation 脚本 返回了错误号 1或2
今天在ubuntu kylin上安装了virtualbox, 后来我想删除了再装个新一点的,结果正常的情况下删除不了,我就把找到的virtualbox的目录全部都删除了, 再通过apt-get rem ...
- android手机连接PC无法正常安装驱动
工作当中我们经常会遇到Android手机连接PC的时候无法正确安装驱动,或者安装失败.当然找到正确的驱动文件时首选的解决方案,如果正确的驱动文件依旧无法安装成功我们可以打开我的电脑-->属性-- ...
- vmware workstation 12 安装windows7 网卡不能安装驱动的问题
在使用vmware workstation 12 安装windows7 之后,网卡不能安装驱动不能正常显示网络连接,需要修改该虚拟机的".vmx"配置文件 在配置文件中添加下面一行 ...
- 2016031901 - ubuntu15.1安装驱动
个人使用u盘安装的ubuntu15.1,安装后找不到无线,主要是驱动没有安装的问题. 解决方案如下: 01.wife无法找到 02.pool文件夹内都是驱动,我们需要的网络驱动也在内 03.网络驱动包 ...
- [置顶] Win8.1慎用360优化,可能导致安装驱动出现数据无效的问题。附解决方法
2013年9月30日,更新说明: 不知道是不是我禁用了其他驱动造成 今天开机后连接手机,我的电脑里没出现MTP设备 于是打开设备管理器,发现MTP,也就是我的XPERIA U出现了感叹号图标 右键更新 ...
- 子进程 已安装 post-installation 脚本 返回错误状态 1,dpkg: 处理软件包 python-crypto (--configure)时出错: 该软件包正处于非常不稳定的状态;
这几天在学习redis的时候,装软件总是报错,两个问题都和dpkg有关,上网查阅了些解决办法,发现整体来说执行以下方法均可解决. 虽然每个人需要安装的包不同,但是出现此类问题的不同也只有安装包的名字, ...
随机推荐
- 转:Durandal快速入门
Durandal是一个轻量级的JavaScript框架,其目标是单页面应用(SPAs)的开发变得简单而优雅.它支持MVC.MVP和MVVM等模式,因此不论你采用哪种类型的前端架构,Durandal都能 ...
- BZOJ3403: [Usaco2009 Open]Cow Line 直线上的牛
3403: [Usaco2009 Open]Cow Line 直线上的牛 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 48 Solved: 41[S ...
- Acdream1157---Segments (CDQ分治)
陈丹琦分治~~~其实一些数据小的时候可以用二维或者多维树状数组做的,而数据大的时候就无力的题目,都可以用陈丹琦分治解决. 题目:由3钟类型操作:1)D L R(1 <= L <= R &l ...
- Java多线程中变量的可见性
之所以写这篇博客, 是因为在csdn上看到一个帖子问的就是这个问题. 废话不多说, 我们先看看他的代码(为了减少代码量, 我将创建线程并启动的部分修改为使用方法引用). 1 2 3 4 5 6 7 8 ...
- JS点击按钮弹出窗口
由于没有系统学习过JS,遇到一个需求:点击按钮,弹出一个独立的窗口. 在网上百度了一下,并没有找到满意的结果,最重要的是各种方法很复杂.最终,仔细研究了一下,原来只是需要只要一个简单的函数就能满足自己 ...
- StackPanel 弹出菜单 ContextMenu
<StackPanel x:Name="stackpanel_zonghe" Margin="0,10,0,0" Background="Tra ...
- Uncaught SyntaxError : Unexpected token ILLEGAL js传递带空格的参数
通常在页面中要让某些内容点击后产生点击事件(非页面跳转)都会使用onclick,但是这样不适于需要传递参数的情况,于是写成直接调用JavaScript函数的方式:<a href=javascri ...
- 程序猿的道路~~(How to be a programmer?)
程序猿的道路其实很简单,主要就是三条: Learn (学习), Practice(练习), Summary(总结) 推荐给新手程序猿两篇文章: 给程序员新手的一些建议 程序员技术练级攻略 当然了,整个 ...
- java中不常见的keyword:strictfp,transient
1.strictfp, 即 strict float point (精确浮点). strictfp keyword可应用于类.接口或方法.使用 strictfp keyword声明一个方法时,该方法中 ...
- WSAWaitForMultipleEvents()
简述:只要指定事件对象中的一个或全部处于有信号状态,或者超时间隔到,则返回. #include <winsock2.h> DWORD WSAAPI WSAWaitForMultipleEv ...