param( [string]$OutputDir = ".\tapi-interop" ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" function Write-Section { param([string]$Text) Write-Host "" Write-Host "==== $Text ====" } Add-Type -TypeDefinition @" using System; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; public static class NetGesconTapiNativeMethods { [DllImport("oleaut32.dll", CharSet = CharSet.Unicode, PreserveSig = false)] public static extern void LoadTypeLib(string file, out ITypeLib typeLib); } public sealed class NetGesconTapiImporterSink : ITypeLibImporterNotifySink { public void ReportEvent(ImporterEventKind eventKind, int eventCode, string eventMsg) { Console.WriteLine("[" + eventKind.ToString() + "] " + eventMsg); } public Assembly ResolveRef(object typeLib) { return null; } } "@ $tapiDll = Join-Path $env:WINDIR 'System32\tapi3.dll' if (-not (Test-Path $tapiDll)) { throw "File non trovato: $tapiDll" } $outputDirectoryInfo = New-Item -ItemType Directory -Force -Path $OutputDir $outputDirectory = $outputDirectoryInfo.FullName $interopFileName = 'Tapi3.Interop.dll' $interopDll = Join-Path $outputDirectory $interopFileName Write-Section 'Generazione interop' Write-Host "sorgente: $tapiDll" Write-Host "destinaz.: $interopDll" $typeLib = $null [NetGesconTapiNativeMethods]::LoadTypeLib($tapiDll, [ref]$typeLib) $converter = New-Object System.Runtime.InteropServices.TypeLibConverter $sink = New-Object NetGesconTapiImporterSink Push-Location $outputDirectory try { $assemblyBuilder = $converter.ConvertTypeLibToAssembly( $typeLib, $interopFileName, 0, $sink, $null, $null, $null, $null ) try { $assemblyBuilder.Save($interopFileName) } catch { Write-Host "[WARN] Save assembly non riuscito: $($_.Exception.Message)" } } finally { Pop-Location } Write-Section 'Caricamento assembly' $assembly = $null if (Test-Path $interopDll) { $assembly = [System.Reflection.Assembly]::LoadFrom($interopDll) Write-Host "Assembly caricato da file: $($assembly.FullName)" } else { $assembly = [System.Reflection.Assembly]$assemblyBuilder Write-Host "Assembly disponibile solo in memoria: $($assembly.FullName)" } $types = $assembly.GetTypes() $eventTypes = @($types | Where-Object { $_.Name -match 'Event' -or $_.FullName -match 'Event' } | Sort-Object FullName) $tapiTypes = @($types | Where-Object { $_.Name -match 'TAPI|Call|Address|Notification' } | Sort-Object FullName) Write-Section 'Tipi con Event nel nome' foreach ($type in $eventTypes) { Write-Host $type.FullName } Write-Section 'Tipi TAPI rilevanti' foreach ($type in $tapiTypes) { Write-Host $type.FullName } Write-Section 'Dettaglio tipi evento ITTAPI' $ittapiRelated = @($types | Where-Object { $_.FullName -match 'ITTAPI' } | Sort-Object FullName) foreach ($type in $ittapiRelated) { Write-Host "" Write-Host $type.FullName foreach ($member in ($type.GetMembers() | Sort-Object MemberType, Name)) { Write-Host (" - {0} {1}" -f $member.MemberType, $member.Name) } } Write-Section 'Dettaglio interfacce evento chiave' $keyTypes = @( 'ITTAPIEventNotification', 'ITTAPIDispatchEventNotification', 'ITCallStateEvent', 'ITCallNotificationEvent', 'ITCallInfoChangeEvent', 'ITCallMediaEvent', 'ITAddressEvent', 'ITTAPIObjectEvent' ) foreach ($typeName in $keyTypes) { $type = $types | Where-Object { $_.Name -eq $typeName } | Select-Object -First 1 if ($null -eq $type) { Write-Host "" Write-Host "$typeName (non trovato)" continue } Write-Host "" Write-Host $type.FullName foreach ($member in ($type.GetMembers() | Sort-Object MemberType, Name)) { Write-Host (" - {0} {1}" -f $member.MemberType, $member.Name) } } Write-Section 'Fatto' if (Test-Path $interopDll) { Write-Host "Interop creato in: $interopDll" } else { Write-Host "Interop disponibile in memoria; file non salvato su disco." } Write-Host "Mandami l'output completo di questo script."