最近用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. RMAN-06023: no backup or copy of datafile 6 found to restore

    一:问题描述 我用指定备份集恢复时,报错: RMAN> run { 2> shutdown immediate; 3> startup mount; 4> allocate c ...

  2. Entity Framework with MySQL 学习笔记一(关系)

    这一篇说说 EF Fluent API 和 DataAnnotations 参考 : http://msdn.microsoft.com/en-us/data/jj591617.aspx http:/ ...

  3. RAILS ON

    我是按照下面这个URL来轻快安装的. http://lxiaodao.iteye.com/blog/1579992 (1)RVM官方网站应该是改版过一次, 使用 curl -L https://get ...

  4. AcitonBar 自定义布局

    Android系统中ActionBar默认的布局不美观且难于控制,通过为ActionBar自定义布局的方式可以灵活控制ActionBar. 自定义Activity主题和ActionBar样式 在新建的 ...

  5. Qt入门(4)——Qt常见控件

    Qt提供了大量的内建控件及通用对话框可满足程序员的绝大部分要求.我们将对这些控件和对话框作一个大概的介绍. 1. QLabel 定义 QLabel* m_labelOrdered = newQLabe ...

  6. Python中的multiprocessing和threading

    Python中的multiprocessing和threading分别使用来实现多进程编程和多线程编程的.其中threading比较简单,而前者比较繁琐. 下面,我们进行一下分析: 多线程--thre ...

  7. python+mysql数据库的简单操作

    最近接了一个任务,测试某项类似于收益情况报表的功能,因计算公式复杂,单纯手算过于复杂,所以想到写成脚本 根据python的分治原则,先整了几个函数用于实现计算逻辑,后发现数据输入过于繁琐,所以决定使用 ...

  8. 为什么选择Premium Fabric Shanghai

    展商首页 为什么选择Premium Fabric Shanghai

  9. paip.输入法编程---带ord gudin去重复-

    paip.输入法编程---带ord gudin去重复- 作者Attilax ,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.n ...

  10. zookeeper[5] zookeeper集群配置及伪集群配置

    参考:http://zookeeper.apache.org/doc/trunk/zookeeperStarted.html 集群配置: 1.配置文件conf/zoo.cfg,除了单机模式的配置之外, ...