Automaticaly installing NDIS filter driver

I’m trying to write a program (or script) to automatically install an NDIS filter driver and accompanying user mode program. How can I do it. Is Driver Package the solution for this problem?
Is the INetCfg interface suitable for this?
If not, what class or technology should I use for this.
Thank You.

How to programmatically install an NDIS filter driver without any user interfaces?
What to use? INetCfg, SetupApi or Windows Installer interface.
In a nutshell. What’s the difference between them?

I did this using INetCfgClassSetup::SelectAndInstall.
Now I want to do this without the UI (INetCfgClassSetup::Install).
But I can’t understand the meaning of the input parameters of this function. In particular the first parameter.

Who can say.
Is there any tutorial to understand how to use NetCfg and everything related to it.
There is some documentation, but no fundamental tutorials.
This area seems very confusing, how to fundamentally understand it.
Where to begin. What book to read.
It seems DDK is not enough for this.
Thank to all.

The microsoft samples on github are a vast resource. See
https://github.com/microsoft/Windows-driver-samples/blob/main/network/config/bindview

Mark Roddy

Thank you Mr Mark_Roddy.
I tried to figure it out for a long time, but this is not a tutorial.
I don’t believe anyone can work with these interfaces professionally with just this example.
Particulary. This example installs a network service using INetCfgClassSetup::SelectAndInstall, which has a user interface
I want to do the same without user interaction (INetCfgClassSetup::Install).
It is very difficult to do something new based on the knowledge gained from this example.

What is wrong here.

    INetCfg* pnc = NULL;
    HRESULT      hr;
    GUID guidClass = GUID_DEVCLASS_NETSERVICE;
    INetCfgClass* pncClass;
    INetCfgClassSetup* pncClassSetup;
    OBO_TOKEN            obo;

    hr = CoInitialize(NULL); //S_OK
    hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER, IID_INetCfg, (LPVOID*)&pnc);  // Create the object implementing INetCfg.
    hr = pnc->Initialize(NULL); //S_OK

    IEnumNetCfgComponent* pEnumComponent;
    INetCfgComponent* pElements;
    ULONG celtFetched;
    wchar_t* pszwDisplayName;
    wchar_t* pszwId;

    GUID classGUID = GUID_DEVCLASS_NETSERVICE;
    hr = pnc->EnumComponents(&classGUID, &pEnumComponent); //S_OK
    hr = pEnumComponent->Next(1, &pElements, &celtFetched); //S_OK
    while (hr == S_OK) {
        pElements->GetDisplayName(&pszwDisplayName);
        pElements->GetId(&pszwId);
        hr = pEnumComponent->Next(1, &pElements, &celtFetched);//"NdisEncrypt NDIS LightWeight Filter" //S_OK
    }   //12 components of NETWORK_SERVICE class, with my already installed (via Windows Ethernet property) NDIS  filter driver
    
    wchar_t *componentID = L"MS_NdisEncrypt";   //ID for my NDIS filter driver given from "pElements->GetId(&pszwId)" function call (from INF file)
    hr = pnc->FindComponent(componentID, &pElements); //S_OK

    hr = pElements->GetClassGuid(&guidClass); //S_OK
    hr = pnc->QueryNetCfgClass(&guidClass,  IID_INetCfgClass,   (PVOID*)&pncClass); //S_OK
    hr = pncClass->QueryInterface(IID_INetCfgClassSetup,   (LPVOID*)&pncClassSetup); //S_OK
    
    ZeroMemory(&obo, sizeof(OBO_TOKEN));
    obo.Type = OBO_USER;   //OBO_COMPONENT,OBO_SOFTWARE
    obo.fRegistered = TRUE;

    LPWSTR pmszwRefs;
    hr = pncClassSetup->D~~~~eInstall(pElements,   &obo,   NULL);     //"it gives error hr = 0x8004a024"  
//  #define NETCFG_S_CAUSED_SETUP_CHANGE                 MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_ITF, 0xA024)
// hr = pncClassSetup->DeInstall(pElements,   &obo,  &pmszwRefs);
    hr = pnc->Apply(); //S_OK

Thank everybody. Everything worked out.
After CoCreateInstance we need to lock interface.

hr = pnc->QueryInterface(IID_INetCfgLock, (LPVOID*)&pncLock);
hr = pncLock->AcquireWriteLock(LOCK_TIME_OUT, lpszAppName, lpszLockedBy);

Well. Another question.
When we get a message ERROR_SERVICE_MARKED_FOR_DELETE (The specified service has been marked for deletion),
in the time of installation( pncClassSetup->Install(szComponentId, &OboToken, 0, 0, NULL, NULL, &pComponent); ),
what we must to do. Attemption to DeInstall does not work out, becouse to find specified service
( pNetCfg->FindComponent(szComponentId, &pComponent); ) сrowning to failure (that service - driver already is not working. Its just marked for deletion). Who can help me. What to do.
How to delete service marked for deletion, programmatically.

Thanks Everyone.

 hr = pnc->QueryNetCfgClass(&guidClass, IID_INetCfgClassSetup, (PVOID*)&pncClassSetup);
 if (hr == S_OK) {
     ZeroMemory(&OboToken, sizeof(OboToken));
     OboToken.Type = OBO_USER;  
     hr = pncClassSetup->Install(szComponentId, &OboToken, 0, 0, NULL, NULL, &pComponent);
     if (hr == S_OK) {
         pComponent->Release();
         pnc->Apply();
         error = 0;
     } else if (LOWORD(hr) == ERROR_SERVICE_MARKED_FOR_DELETE)  {    // The specified service has been marked for deletion.
**_//What to do ?_**
         error = 10;
     } else {
        error = 11;
     }
     efINetCfg = pnc->Release();
 }

That usually means (a) the service was running, (b) someone tried to delete it, and (c) the service has not agreed to stop. If that’s the situation, then the only solution is to reboot to get the service manager back into a good state.