我想以编程方式安装MS环回适配器以自动tunneling of SMB over SSH。
我在网上找到的所有代码都使用MS devcon实用程序,该实用程序不可再分发(参见http://support.microsoft.com/kb/311272/en-us)。示例用法(更多示例):
devcon -r install %WINDIR%\Inf\Netloop.inf *MSLOOP
除了可分发性问题之外,理想情况下我希望能够控制所得到的设备名称,尽管可以通过枚举前后的网络适配器并寻找新的MS环回设备来解决这个问题。这有点活泼,虽然我觉得我可以忍受它。我的想法是调整一些this code。
我正在查看WDK的devcon源代码,通过SetupAPI / CfgMgr32添加环回适配器,如上面链接的MS KB文章所示。有没有更容易/可编写脚本的方式?
如果没有,是否有人为该SetupAPI / CfgMgr32路由提供了一些相对简单的示例代码?
答案 0 :(得分:4)
我想在不编写任何新exe的情况下实现同样的目的,并且发现可以使用cscript和devcon和netsh工具完成。创建适配器似乎无法控制它将被调用的内容,因此您必须在创建它之后使用WMI接口进行枚举。不幸的是,netsh的行为取决于你所使用的Windows版本,但是在名为create-loopback.vbs的文件中打了下面的内容,它将在XP和2008服务器上运行。
Dim strLastLoopbackAdapterName, loopbackAdapterName
If wscript.arguments.count < 3 then
WScript.Echo "usage: create-loopback.vbs loopbackAdapterName loopbackIpAddress loopbackSubNetMask "
WScript.Quit
end If
loopbackAdapterName = wscript.arguments(0)
loopbackIpAddress = wscript.arguments(1)
loopbackSubNetMask = wscript.arguments(2)
Wscript.Echo "Creating loopback called " &loopbackAdapterName &" on " &loopbackIpAddress &" with mask " &loopbackSubNetMask
Set objShell = CreateObject("WScript.Shell")
Wscript.Echo "Installing loopback adapter..."
objShell.Run "cmd /c devcon install %windir%\inf\netloop.inf *MSLOOP", 0, True
Wscript.Echo "Waiting for drivers to update..."
Wscript.sleep 10000 'Allow 10s for install'
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT NetConnectionID FROM Win32_NetworkAdapter WHERE Name='Microsoft Loopback Adapter'", "WQL", 48)
For Each objItem In colItems
strLastLoopbackAdapterName = objItem.NetConnectionID
Next
Wscript.Echo "Last Loopback Connection is " & strLastLoopbackAdapterName
Wscript.Echo "Renaming new loopback..."
objShell.Run "netsh interface set interface name = " &Chr(34) &strLastLoopbackAdapterName &Chr(34) &" newname = " &Chr(34) &loopbackAdapterName &Chr(34), 0, True
Wscript.Echo "Configuring loopback..."
objShell.run "netsh interface ip set address name=" &Chr(34) &loopbackAdapterName &Chr(34) &" source=static " &loopbackIpAddress &" " &loopbackSubNetMask, 0, True
Wscript.Echo "Done"
WScript.Quit(0)
答案 1 :(得分:2)
答案 2 :(得分:2)
希望我对派对来说还不算太晚 - 没有devcon / vbs这样做是可能的(尽管需要许多本地pinvoke调用):
要安装环回适配器,请使用参数"C:\Windows\Inf\netloop.inf"
,*MSLOOP
调用以下方法:
class Devcon
{
//https://msdn.microsoft.com/en-us/magazine/dd419661.aspx?f=255&MSPPError=-2147217396#id0070035
[HandleProcessCorruptedStateExceptions]
static bool InstallDriver(string inf, string hwid)
{
StringBuilder className = new StringBuilder(MAX_CLASS_NAME_LEN);
Guid ClassGUID = Guid.Empty;
if (!SetupDiGetINFClass(inf, ref ClassGUID, className, MAX_CLASS_NAME_LEN, 0))
return false;
IntPtr DeviceInfoSet = SetupDiCreateDeviceInfoList(ref ClassGUID, IntPtr.Zero);
SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();
if (!SetupDiCreateDeviceInfo(DeviceInfoSet, className.ToString(), ref ClassGUID, null, IntPtr.Zero, DICD_GENERATE_ID, DeviceInfoData))
return false;
if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_HARDWAREID, hwid, hwid.Length))
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return false;
}
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, DeviceInfoData))
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return false;
}
// http://stackoverflow.com/questions/11474317/updatedriverforplugandplaydevices-error-is-telling-me-im-not-doing-something
try
{
bool reboot = false;
if (!UpdateDriverForPlugAndPlayDevices(IntPtr.Zero, hwid, inf, 0, reboot))
{
SetupDiCallClassInstaller(DIF_REMOVE, DeviceInfoSet, DeviceInfoData);
return false;
}
}
catch (AccessViolationException) { }
return true;
}
// Consts
const int MAX_CLASS_NAME_LEN = 32;
const int SPDRP_HARDWAREID = 0x00000001;
const int DICD_GENERATE_ID = 0x00000001;
const int DIF_REGISTERDEVICE = 0x00000019;
const int DIF_REMOVE = 0x00000005;
// Pinvokes
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiGetINFClass(string infName, ref Guid ClassGuid, [MarshalAs(UnmanagedType.LPStr)] StringBuilder ClassName, int ClassNameSize, int RequiredSize);
[DllImport("setupapi.dll", SetLastError = true)]
static extern IntPtr SetupDiCreateDeviceInfoList(ref Guid ClassGuid, IntPtr hwndParent);
[DllImport("Setupapi.dll", SetLastError = true)]
static extern bool SetupDiCreateDeviceInfo(IntPtr DeviceInfoSet, String DeviceName, ref Guid ClassGuid, string DeviceDescription, IntPtr hwndParent, Int32 CreationFlags, SP_DEVINFO_DATA DeviceInfoData);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiSetDeviceRegistryProperty(IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData, uint Property, string PropertyBuffer, int PropertyBufferSize);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
[DllImport("setupapi.dll", SetLastError = true)]
static extern bool SetupDiCallClassInstaller(UInt32 InstallFunction, IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData);
[DllImport("newdev.dll", SetLastError = true)]
static extern bool UpdateDriverForPlugAndPlayDevices(IntPtr hwndParent, string HardwareId, string FullInfPath, int InstallFlags, bool bRebootRequired);
// Structs
[StructLayout(LayoutKind.Sequential, Pack = 8)]
class SP_DEVINFO_DATA
{
internal int cbSize = Marshal.SizeOf(typeof(SP_DEVINFO_DATA));
[MarshalAs(UnmanagedType.Struct)]
internal Guid classGuid = Guid.Empty; // temp
internal int devInst = 0; // dumy
internal long reserved = 0;
}
}
以上内容适用于x64操作系统。为了使其能够在x86操作系统上运行,请将Pack = 8
结构中的Pack = 1
更改为SP_DEVINFO_DATA