最近用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. NET Core & VS Code 之路(2) Web API

    NET Core & VS Code 之路(2) Web API 开发Core项目的条件 Visual Studio 2015 Update 3 .NET Core 1.0.0 - VS 20 ...

  2. Cloudera Search配置

    一.集群机器配置信息 Cloudera集群机器: 10.2.45.104 GBD000.localdomain GBD00010.2.45.105 GBD101.localdomain GBD1011 ...

  3. C++代码覆盖率工具Coverage Validator

    市面上的C++代码覆盖率工具大都收费,Coverage Validator也不例外.Coverage Validator应该少有人听过,我也是在stackoverflow里听别人介绍的.所以下载了试用 ...

  4. cf500C New Year Book Reading

    C. New Year Book Reading time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  5. Android中sharedPreference的简单使用

    public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super ...

  6. ACM2114_S[I](1^3+2^3+3^3)

    #include<iostream> using namespace std; int main() { __int64 n,m,i,j,sum; while(cin>>n) ...

  7. BNUOJ34990--Justice String (exkmp求最长公共前缀)

    Justice String Given two strings A and B, your task is to find a substring of A called justice strin ...

  8. HDU-3787(字符串模拟)

    Problem Description 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号","隔开.现在请计算A+B的结果,并以正常形式输出.   Input 输入包含 ...

  9. 【转】windows下vs2008/2010+opencv2.2开发环境搭建

    版权声明:本文为博主原创文章,未经博主允许不得转载. 1.下载安装Cmake 2.用cmake配置opencv2.2,然后编译,安装 3. 在vs2008中配置opencv2.2 4.Demo 1.下 ...

  10. shell中的替换

    shell中如果存在一些特殊的字符,就需要进行替换,可进行命令替换.变量替换.转义替换 1.转义字符的替换 shell中包含以下的转移字符 \a   响铃警报\\   反斜杠 \b  退格(删除键) ...