Вопрос по delphi, ole, forwarding, port – Переадресация портов с использованием объекта Ole «HNetCfg.NATUPnP» не удалась

2

Я использую код для переадресации порта. этот код отлично работает на My Windows 7; Но я могу'использовать его в Windows XP.

Обновление 1 для проблемы (2012-10-17 07: 32: 00Z)

Это мой исходный код:

uses
  ActiveX, oleAuto;

Procedure AddUPnPEntry(Port: Integer; const Name: ShortString; LAN_IP: string);
Var
  Nat: Variant;
  Ports: Variant;
  SavedCW: Word;
Begin
  if NOT(LAN_IP = '127.0.0.1') then
  begin
    try
      Nat := CreateOleObject('HNetCfg.NATUPnP');
      Ports := Nat.StaticPortMappingCollection;

      // Error Raized From Here!!!
      ShowMessage(inttostr(Ports.count));

      Ports.Add(Port, 'TCP', Port, LAN_IP, True, name);
    except
      ShowMessage('An Error occured with adding UPnP Ports. The ' + name +
        ' port was not added to the router. Please check to see if  your ' +
        'router supports UPnP and has it enabled or disable UPnP.');
    end;
  end;
End;

procedure TForm1.Button2Click(Sender: TObject);
begin
  AddUPnPEntry(1234, 'Hello3', '192.168.1.1');
end;

Сообщение об ошибке AV:

Project Project1.exe raised exception class $C0000005 with message 'access violation at 0x00504876: read of address 0x00000000'.
@ShaahinAshayeri я 'я подключен к чему-то под названием HotBox, который похож на комбинацию модем / маршрутизатор,В нем нет виртуального сервера, но я понимаю, что вымы говорим о том, что Virtual Server - это то, что у меня есть в моем другом маршрутизаторе от Dlink. user1803300
@Shuhin - Глядя на РРУЗЬОтвет, ясно, что ваш вопрос не совсем ясен. Учитывая, что это не спросили, это не удивительно .. Sertac Akyuz
Просто вопрос, когда вы добавляете запись, где я могу ее увидеть? user1803300
@KenWhite, я забыл написать AV Error. Моя проблема обновлена. Благодарю. Shaahin Ashayeri

Ваш Ответ

4   ответа
1

Проверьте свое шоу с этим кодом

ShowMessage (VarToStrDef (Ports.Count»ничего такого');

код неэто не работает, потому что когда компилятор обращается к ports.count, происходит нарушение прав доступа. JO SeongGng
3

Для тех, кто видит это, функциональность UPnP отличается от XP, вот что я использую:

TWindowsName = ( WINXP, WINVISTA, WIN7, WIN80, WIN81 );

var
  fWindowsName : TWindowsName;

procedure InitializeWindowsName;
var
  WinVersion  : TOSVersionInfo;

begin

  WinVersion.dwOSVersionInfoSize := sizeof ( WinVersion );
  GetVersionEx ( WinVersion );

  if WinVersion.dwMajorVersion = 5 then
    fWindowsName := WINXP    
  else if WinVersion.dwMajorVersion = 6 then
    fWindowsName := TWindowsName ( WinVersion.dwMinorVersion + 1 );

end;

procedure AddPortThroughUPnP ( const APort: WORD; const AProtocol, ALocalIP, AName: String );
var
  NAT      : Variant;
  Profile  : Variant;
  Ports    : Variant;
  Protocol : Integer;

begin

  if not fEnableUPnP then exit;

  if fWindowsName = WINXP then
  begin

    NAT      := CreateOleObject ( 'HNetCfg.FwMgr' );
    Profile  := NAT.LocalPolicy.CurrentProfile;

    if not VarIsClear ( Profile ) then
    begin

      if AProtocol = 'UDP' then Protocol := 17
      else if AProtocol = 'TCP' then Protocol := 35; 

      Ports          := CreateOLEObject('HNetCfg.FWOpenPort');
      Ports.Name     := AName;
      Ports.Port     := APort;
      Ports.Scope    := 0;
      Ports.Protocol := Protocol;
      Ports.Enabled  := True;

      Profile.GloballyOpenPorts.Add ( Ports );

    end;

  end
  else
  begin

    NAT   := CreateOleObject ( 'HNetCfg.NATUPnP' );
    Ports := NAT.StaticPortMappingCollection;

    if not VarIsClear ( Ports ) then
       Ports.Add ( APort, AProtocol, APort, ALocalIP, True, AName );

  end;

end;

Можно пропустить инициализацию имени Windows и поставить вместо этого собственный алгоритм проверки.

@JOSeongGng Приведенное выше решение зависит от версии WinAPI. Лучше всего проверить наличие изменений в его архитектуре в Windows 10. Приведенное выше решение было протестировано для Windows до 8.1. Umair Ahmed
8

Если вы получаете нарушение прав доступа, то при доступе к свойству count это означает, чтоIStaticPortMappingCollection интерфейс, возвращаемыйIUPnPNAT.get_StaticPortMappingCollection методnilЭто может быть вызвано многими причинами, по которым ваше устройствоt поддерживает UPnP, UPnP не включен на устройстве, пользовательский интерфейс UPnP не установлен / активен и т. д.

В любом случае, чтобы предотвратить подобные исключения (нарушение прав доступа), вы должны проверить значение, возвращаемое свойством или методом, прежде чем использовать его, в этом случае вы можете использоватьVarIsClear функционировать так:

try
  Nat := CreateOleObject('HNetCfg.NATUPnP');
  Ports := Nat.StaticPortMappingCollection;

  if not VarIsClear(Ports) then
  begin
    //do something
    ShowMessage(inttostr(Ports.count));
    Ports.Add(Port, 'TCP', Port, LAN_IP, True, name);
  end;

except on E:Exception do
  ShowMessage('An Error occured with adding UPnP Ports. '+E.Message);
end;
Я просто могуЕсли я не общаюсь напрямую с другими компьютерами за пределами моей локальной сети, я включил UPNP на своем маршрутизаторе, но ничего не изменилось. Please_Dont_Bully_Me_SO_Lords
Хороший совет, спасибо. Я'Я не уверен, но я думаю, что это ошибка Windows? в качестве примера, пожалуйста, посмотрите на это:barnamenevis.org/showthread.php?336275" . Shaahin Ashayeri
У меня не получилось :-( Please_Dont_Bully_Me_SO_Lords
-1

Если бы ты неЧтобы решить проблему, вот ответ:

Удалить "ShowMessage ...» потому что когда ты неНа роутере нет записей, вы получили ошибку. Я проверил, и это работает.

В моей системе это не работает. Shaahin Ashayeri
Ваше решение неэффективно, потому что при запуске ports.add происходит нарушение прав доступа. JO SeongGng

Похожие вопросы