вызвать системную команду Windows через fortran без отображения окна оболочки и вывести результат во внешний файл

Я делаю небольшой проект с использованием Фортрана. Часть кода предназначена для проверки MAC-адреса ПК. В настоящее время я использую команду системы вызова следующим образом:

CALL SYSTEM("ipconfig -all >result.tmp") Приведенный выше код вызовет команду windows ipconfig-all и выведет информацию во внешний файл result.tmp. Позже этот файл будет прочитан для проверки MAC-адреса.

https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-fo ...

Я пробовал это решение, оно отлично работает с системной командой «ipconfig -all», но я не понял, как вывести результат во внешний файл. Кто-нибудь может дать мне несколько советов о том, как этого добиться?

Выше работает, кроме одной неприятной вещи. Код Fortran будет скомпилирован как DLL и использоваться другой программой C #. Раздражает то, что всякий раз, когда приведенный выше код выполняется в программе C #, окно консоли сразу же запрашивается, а затем закрывается. Я искал на форуме, есть ли способ отключить подсказку в окне, оказалось, что по следующей ссылке есть какое-то решение:


person Eric    schedule 06.01.2019    source источник
comment
Ваша ссылка неверна. Следующая ссылка на и вообще отсутствует. Что происходит, когда вы делаете свой CALL SYSTEM("ipconfig -all >result.tmp")? Файл результатов не создан? Что именно происходит вместо этого?   -  person Vladimir F    schedule 07.01.2019
comment
SYSTEM не вызывает оболочку, поэтому перенаправление работать не будет. Я попробовал ShellExecute, но и там перенаправление не работало. В общем, я бы рекомендовал вместо этого использовать подпрограммы Windows API для программного получения MAC-адреса, а не пытаться анализировать вывод ipconfig (который может измениться или может иметь несколько адаптеров). Функция GetAdaptersAddresses сделает это, но вам придется написать ваш собственный интерфейс, поскольку Intel не включает его.   -  person Steve Lionel    schedule 07.01.2019


Ответы (1)


Вы также разместили это на странице Форум Intel и пользователь Пол Кертис ответил примером того, как получить MAC-адрес напрямую с помощью Windows API.

Поскольку StackOverflow предпочитает ответы, а не просто ссылки, я включил приведенный ниже код.

MODULE MAC  
    USE ifwinty  
    USE charfunc
    IMPLICIT NONE 
    PUBLIC GetMacInfo       !, PortExists
    PRIVATE
    SAVE

    INTEGER, PARAMETER :: MAX_ADAPTER_DESCRIPTION_LENGTH = 128  
    INTEGER, PARAMETER :: MAX_ADAPTER_NAME_LENGTH        = 256  
    INTEGER, PARAMETER :: MAX_ADAPTER_ADDRESS_LENGTH     =   8  
    INTEGER, PARAMETER :: MIB_IF_TYPE_ETHERNET           =   6  ! Ipifcons.h

    TYPE IP_ADDRESS_STRING  
        CHARACTER(LEN=16) :: String  
    END TYPE IP_ADDRESS_STRING

    TYPE IP_MASK_STRING  
        CHARACTER(LEN=16) :: String  
    END TYPE IP_MASK_STRING

    TYPE t_IP_ADDR_STRING   
        INTEGER (LPLONG)         :: pNext  
        TYPE (IP_ADDRESS_STRING) :: IpAddress  
        TYPE (IP_MASK_STRING)    :: IpMask  
        INTEGER (DWORD)          :: Context  
    END TYPE t_IP_ADDR_STRING

    TYPE t_IP_ADAPTER_INFO  
        INTEGER(LPLONG)         :: pNext   
        INTEGER(DWORD)          :: ComboIndex  
        CHARACTER(LEN=MAX_ADAPTER_NAME_LENGTH+4)        :: AdapterName  
        CHARACTER(LEN=MAX_ADAPTER_DESCRIPTION_LENGTH+4) :: Description  
        INTEGER(UINT)           :: AddressLength  
        INTEGER(BYTE)           :: Address(MAX_ADAPTER_ADDRESS_LENGTH)  
        INTEGER(DWORD)          :: Index  
        INTEGER(ULONG)          :: iType  
        INTEGER(ULONG)          :: DhcpEnabled  
        INTEGER(LPLONG)         :: pCurrentIpAddress   
        TYPE(t_IP_ADDR_STRING)  :: IpAddressList  
        TYPE(t_IP_ADDR_STRING)  :: GatewayList  
        TYPE(t_IP_ADDR_STRING)  :: DhcpServer  
        INTEGER(BOOL)           :: HaveWins  
        TYPE(t_IP_ADDR_STRING)  :: PrimaryWinsServer  
        TYPE(t_IP_ADDR_STRING)  :: SecondaryWinsServer  
        INTEGER(ULONG)          :: LeaseObtained  
        INTEGER(ULONG)          :: LeaseExpires  
    END TYPE t_IP_ADAPTER_INFO

    !   must link with IpHlpApi.lib to access this API function;
    !   this interface is not included in ifwinty
    INTERFACE  
        INTEGER(BOOL) FUNCTION GetAdaptersInfo (arg1, arg2)  
            USE ifwinty  
            !DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'GetAdaptersInfo' :: GetAdaptersInfo  
            INTEGER(LPLONG) :: arg1  
            INTEGER(LPLONG) :: arg2  
        END FUNCTION  
    END INTERFACE

CONTAINS  


    SUBROUTINE GetMacInfo (hwnd, id)
        USE contwrap
        IMPLICIT NONE

        !   dialog window handle and set of static-text IDs for display
        INTEGER(HANDLE), INTENT(IN)         :: hwnd
        INTEGER, INTENT(IN), DIMENSION(4)   :: id 

        CHARACTER(LEN=200)                  :: msg
        INTEGER                             :: i, nc, count
        INTEGER, PARAMETER                  :: acount = 16
        TYPE(t_IP_ADAPTER_INFO),ALLOCATABLE :: ai(:)  

        count = 0

        !   allow for multiple adapters
        ALLOCATE (ai(acount))
        nc = SIZEOF(ai)
        IF (GetAdaptersInfo(LOC(ai), LOC(nc)) == 0) THEN  

            DO i = 1, acount
                SELECT CASE (ai(i)%iType)
                CASE (MIB_IF_TYPE_ETHERNET)

                    !   line 1: description and MAC address
                    !nc = INDEX(ai(i)%Description, CHAR(0)) - 1
                    !WRITE (msg, '(A,",  ",5(Z2.2,"-"),Z2.2)') &
                    !    ai(i)%Description(1:nc),              &
                    !    ai(i)%Address(1:ai(i)%AddressLength)
                    nc = INDEX(ai(i)%Description, CHAR(0))
                    msg = ai(i)%Description(1:nc)
                    count = count + 1
                    CALL StaticSetText (hwnd, id(count), msg)
                    CALL ControlSetVisible (hwnd, id(count), .TRUE.)

                    !   line 2: IP and Gateway addresses
                    WRITE (msg, '("IP Addr: ",A,"  Gateway: ",A)')  &
                        ai(i)%IpAddressList%IpAddress%string,       &
                        ai(i)%GatewayList%IpAddress%string
                    CALL remove_nulls (msg)
                    count = count + 1
                    CALL StaticSetText (hwnd, id(count), msg)
                    CALL ControlSetVisible (hwnd, id(count), .TRUE.)

                    IF (count >= 4) EXIT
                END SELECT
                IF (ai(i)%pNext == NULL) EXIT  
            END DO

        END IF
        DEALLOCATE (ai)

    END SUBROUTINE GetMacInfo

END MODULE MAC
person Steve Lionel    schedule 07.01.2019
comment
Искренне признателен доктору Фортрану за вашу помощь. А также помощь Пола. Я попробую приведенные выше коды, чтобы увидеть, работает ли это. - person Eric; 08.01.2019
comment
Есть гораздо более простой способ, если 1) вы все еще хотите анализировать вывод ipconfig, 2) у вас Intel Fortran 16 или новее: call execute_command_line ('ipconfig -all > ipx.txt') - person Steve Lionel; 09.01.2019
comment
Является ли Intel Fortran 16 полностью обратно совместимой с IVF 2013? Если это так, я могу подумать о переходе на Fortran 16 вместо этого - person Eric; 18.01.2019