2011-01-17 3 views
3

Ich möchte den MS Loopback-Adapter programmgesteuert installieren, um tunneling of SMB over SSH zu automatisieren.Microsoft Loopback-Adapter programmgesteuert von VBS (oder C#/VB) installieren

Der gesamte Code, den ich im Internet gefunden habe, verwendet das Dienstprogramm MS devcon, das nicht weitervertreibbar ist (vgl. http://support.microsoft.com/kb/311272/en-us). Beispielverwendung (weitere Beispiele):

devcon -r install %WINDIR%\Inf\Netloop.inf *MSLOOP 

Neben der Verteilbarkeit Frage, wie ich würde im Idealfall eines gewisse Kontrolle über die resultierenden Gerätenamen haben, obwohl die durch Aufzählen des Netzwerkadapters festgelegt werden kann, bevor und nach und auf der Suche für das neue MS-Loopback-Gerät. Das ist ein bisschen rassig, obwohl ich denke, dass ich damit leben könnte. Meine Idee ist es, einige von this code anzupassen.

Ich bin derzeit in der Devcon Quellcode von der WDK suchen, um die Loopback-Adapter über SetupAPI/CfgMgr32 wie der MS KB Artikel oben verlinkt, schlägt vor. Gibt es einen einfacheren/skriptfähigen Weg?

Wenn es keine gibt, hat jemand einige relativ einfachen Beispielcode für diese Route SetupAPI/CfgMgr32?

+0

Hier ändern ist ein verwandter [KB-Artikel] (http://support.microsoft.com/kb/839013) mit einem Skript für die automatische Installation. – Zarat

+0

@ Zarat: Ich sah, dass KB-Artikel, aber Googling für unattand.txt zeigt, dass es nur für die unbeaufsichtigte Neuinstallation von Windows auf Computern verwendet wird. Ich habe keine Möglichkeit gesehen, später eine Unattend.txt-Datei zu verwenden, sobald Windows installiert ist. Habe ich etwas verpasst? –

+0

Ah, ich denke du hast Recht, tut mir leid. – Zarat

Antwort

4

ich die gleiche Sache ohne das Schreiben keine neuen exe erreichen wollte, es zu tun und finden kann es mit cscript und der devcon und netsh-Tools durchgeführt werden. Das Erstellen des Adapters scheint Ihnen keine Kontrolle darüber zu geben, wie er aufgerufen wird. Sie müssen also die WMI-Schnittstelle aufzählen, nachdem Sie sie erstellt haben. Leider hängt Netsh-Verhalten davon ab, auf welcher Version von Windows Sie sich befinden, aber folgendes in einer Datei namens create-loopback.vbs und es wird auf XP und 2008 Server funktionieren.

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

ich hoffe nicht zu spät für die Partei bin - es ohne devcon tun/vbs ist möglich (wenn auch viele einheimische pinvoke Anrufe erforderlich sind):

Um das Loopback-Adapter installieren möchten, rufen Sie die Verfahren mit den folgenden Parametern "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; 
    } 
} 

Die oben auf x64 OSs funktionieren. um es auf x86-Betriebssystemen zu arbeiten, Pack = 8-Pack = 1 in dem SP_DEVINFO_DATA struct

+1

Nissims Lösung funktioniert großartig - danke. Ich denke, es ist erwähnenswert, dass, damit es auf x64-Plattformen funktioniert, es als x64 oder irgendeine CPU kompiliert werden muss. Für einige von Ihnen mag das ein bisschen vernünftig erscheinen, aber ich habe diesen Code in eine Testanwendung geworfen und dann eine Stunde lang Win32-Fehler ausfindig gemacht und mir den Kopf darüber gemacht, warum SP_DEVINFO_DATA.cbSize anscheinend nie richtig funktioniert schließlich feststellen, dass das Problem war, dass ich als x86 (standardmäßig) kompiliert wurde. Vielleicht wird dies jemandem Zeit sparen. – Pete