最近用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的更多相关文章

  1. 用Setup系列函数完成驱动卸载安装[驱动安装卸载程序]

    // InstallWDFDriver.cpp : Defines the entry point for the console application. // #include "std ...

  2. monkeyrunner之电脑安装驱动(五)

    在Monkeyrunner做自动化测试时,可以使用模拟器,当然也可以选择用真机.不过,要想通过电脑来安装软件,操作手机,则必须先安装手机驱动,而且一般手机连接电脑之后,电脑会自动开始下载驱动.不过也经 ...

  3. JZ2440开发板学习 1. 刚接触开发板, 安装驱动

    一. jtag和串口驱动 1. 驱动下载 http://pan.baidu.com/s/1pJkAHJH 2. 驱动安装 禁用win10的驱动数字签名 http://www.100ask.org/bb ...

  4. 子进程 已安装 pre-removal 脚本 返回了错误号 1或2 与 子进程 已安装 post-installation 脚本 返回了错误号 1或2

    今天在ubuntu kylin上安装了virtualbox, 后来我想删除了再装个新一点的,结果正常的情况下删除不了,我就把找到的virtualbox的目录全部都删除了, 再通过apt-get rem ...

  5. android手机连接PC无法正常安装驱动

    工作当中我们经常会遇到Android手机连接PC的时候无法正确安装驱动,或者安装失败.当然找到正确的驱动文件时首选的解决方案,如果正确的驱动文件依旧无法安装成功我们可以打开我的电脑-->属性-- ...

  6. vmware workstation 12 安装windows7 网卡不能安装驱动的问题

    在使用vmware workstation 12 安装windows7 之后,网卡不能安装驱动不能正常显示网络连接,需要修改该虚拟机的".vmx"配置文件 在配置文件中添加下面一行 ...

  7. 2016031901 - ubuntu15.1安装驱动

    个人使用u盘安装的ubuntu15.1,安装后找不到无线,主要是驱动没有安装的问题. 解决方案如下: 01.wife无法找到 02.pool文件夹内都是驱动,我们需要的网络驱动也在内 03.网络驱动包 ...

  8. [置顶] Win8.1慎用360优化,可能导致安装驱动出现数据无效的问题。附解决方法

    2013年9月30日,更新说明: 不知道是不是我禁用了其他驱动造成 今天开机后连接手机,我的电脑里没出现MTP设备 于是打开设备管理器,发现MTP,也就是我的XPERIA U出现了感叹号图标 右键更新 ...

  9. 子进程 已安装 post-installation 脚本 返回错误状态 1,dpkg: 处理软件包 python-crypto (--configure)时出错: 该软件包正处于非常不稳定的状态;

    这几天在学习redis的时候,装软件总是报错,两个问题都和dpkg有关,上网查阅了些解决办法,发现整体来说执行以下方法均可解决. 虽然每个人需要安装的包不同,但是出现此类问题的不同也只有安装包的名字, ...

随机推荐

  1. LINQ 学习笔记(1)

    学习资源参考 : http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html 常用方法是 Where, OrderBy, Selec ...

  2. 单片机设计与KeilC编程总结

    1基本原则    质量是关键.没有人会对很差的工作感到满足.当完成高质量的工作时,你会为此而感到骄傲.不管你是否知道,你都会因为你的高质量工作而得到信誉.因此,要想为自己所做的事感到骄傲,就需要建立个 ...

  3. jmap命令结合mat插件分析内存泄露--OQL

    http://smallnetvisitor.iteye.com/blog/1826434 User.java package gc; import java.util.ArrayList; impo ...

  4. 注意:rsyslog 源码安装 会出现日志重复发的情况,需要rpm包安装

    cd /etc/yum.repos.d;wget http://rpms.adiscon.com/v8-stable/rsyslog.repo uat-web02:/etc/yum.repos.d# ...

  5. 【HDOJ】1332 LC-Display

    水题. #include <cstdio> #include <cstring> #include <cstdlib> #define MAXN 11 #defin ...

  6. SPOJ 0962 Intergalactic Map

    题目大意:在一个无向图中,一个人要从A点赶往B点,之后再赶往C点,且要求中途不能多次经过同一个点.问是否存在这样的路线.(3 <= N <= 30011, 1 <= M <= ...

  7. HDU_2037——最多电视节目问题

    Problem Description “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...”确实如此,世界杯来了,球迷的节日也来了,估计很多 ...

  8. [置顶] 宏途_LCD调试流程.

    今天在调试宏途的LCD屏时,开始是开机屏幕不亮,背光都不亮,可能板子已经损坏,一般通过测试电流电压简单验证,(注:硬件引脚没焊好也会引起读lcd id出现错误!!!)出现这个问题一般是因为引脚没焊好, ...

  9. UVa 10048: Audiophobia

    这道题要求我们求出图中的给定的两个节点(一个起点一个终点,但这是无向图)之间所有“路径中最大权值”的最小值,这无疑是动态规划. 我开始时想到根据起点和终点用动态规划直接求结果,但最终由于题中S过大,会 ...

  10. iOS BMOB-登录注册手机验证码、邮箱验证

    1.下载BmobSDK 2.把里面的BmobSDK.framework拖到你的工程里面的工具文件夹内. 3.导入类库 CoreLocation.framework.Security.framework ...