Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Determining a running Fortran program's "residence directory" 2

Status
Not open for further replies.

Deniall

Technical User
May 15, 2011
250
Australia
This is a repeat of a post I put on Eng-Tips about a fortnight ago.[ ] See
for that post and the replies it elicited.[ ][ ] It looks like I will not be able to achieve my aim in this matter, but I thought it worth trying this forum before I resign myself to this fate.

I am trying to get an old Fortran program to run on a modern Windows computer.[ ] Progress is slow but steady.[ ] However I have struck an "interesting" little problem.[ ] My program's *.EXE file will reside in a directory that will be chosen by the end user, with different users choosing to store it in different places.[ ] Users will run the program from a "Command Prompt" window, by typing its name and perhaps its residence directory.[ ] Thus they might type:
» ProgName[ ][ ] (if the program resides in the current working directory or in a directory that is on the system's "path")
» D:\MySoftware\etc\etc\ProgName[ ][ ] (an absolute address for the residence directory)
» ..\ProgName[ ][ ] (if the program resides in the directory above the current working directory)

I am looking for a way for the program to find out the full name of its residence directory.[ ] Gfortran has a subroutine GETCWD(cwd) that returns the full name of the directory the user is "sitting in", but I have been unable to find a way to obtain the program's residence directory.

Does anyone know of a way to achieve this?
 
Hi,

To get current directory in windows you can use the windows CD command.
and to execute the windows command from the fortran program you can use SYSTEM() function/subroutine. Try something like this in your fortran program:
Code:
cmd_string = "cd > current_directory.txt"

cmd_rc = system (cmd_string)

if ( cmd_rc .ne. 0 ) stop 'system: Error !!!'
then your program can read the current directory from the file current_directory.txt
 
Thanks, Mikrom.[ ] However I think you have misunderstood what I am after.[ ] I'm not after the "current directory".[ ] I can get this from the semi-standard GETCWD subroutine, which returns the name of the directory my user is sitting in when he types the name of my .EXE program to run it.[ ] However the .EXE program is not necessarily in that directory.[ ] In fact it would be good practice (IMHO) for the program NOT to reside in that directory.[ ] The program will be in some other directory, a directory that is on the system's "path".[ ] In a networked environment, the program might even reside on a different computer, not just in a different directory.
 
Hi Deniall,
I thought that the command returns the name of directory where the program resides. But now I tried it and - you are right - it returns the directory where the user who calls the program is sitting.
 
Hi Deniall,

It seems that this problem is not solvable with pure fortran program.
But with fortran we can use C/C++.

I found here how to get the path of the running exe in C++:
and here how to get from the given exe path only the directory path:

Then based on the links above I wrote this code in C++:
get_exe_path.c
Code:
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<string>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<windows.h>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<iostream>[/color]

std::string get_exe_path();
std::string get_directory([COLOR=#2e8b57][b]const[/b][/color] std::string&);
[COLOR=#2e8b57][b]extern[/b][/color] [COLOR=#ff00ff]"C"[/color] [COLOR=#2e8b57][b]void[/b][/color] getdir_();

std::string get_exe_path()
{
  [COLOR=#2e8b57][b]char[/b][/color] result[ MAX_PATH ];
  [COLOR=#804040][b]return[/b][/color] std::string( result, GetModuleFileName( [COLOR=#ff00ff]NULL[/color], result, MAX_PATH ) );
}

std::string get_directory([COLOR=#2e8b57][b]const[/b][/color] std::string &path)
{
    [COLOR=#2e8b57][b]size_t[/b][/color] found = path.find_last_of([COLOR=#ff00ff]"/[/color][COLOR=#6a5acd]\\[/color][COLOR=#ff00ff]"[/color]);
    [COLOR=#804040][b]return[/b][/color](path.substr([COLOR=#ff00ff]0[/color], found));
}

[COLOR=#2e8b57][b]extern[/b][/color] [COLOR=#ff00ff]"C"[/color] [COLOR=#2e8b57][b]void[/b][/color] getdir_() 
{
   std::cout << get_directory(get_exe_path()) << [COLOR=#ff00ff]"[/color][COLOR=#6a5acd]\n[/color][COLOR=#ff00ff]"[/color];
}

[COLOR=#0000ff]/*[/color]
[COLOR=#0000ff]int main() {[/color]
[COLOR=#0000ff]  getdir_();[/color]
[COLOR=#0000ff]}[/color]
[COLOR=#0000ff]*/[/color]
You can uncomment main and run or debug the program, to see how it works.

Then I wrote this fortran code which calls the C code:
get_program_dir.f95
Code:
[COLOR=#a020f0]program[/color] get_program_dir
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color])[COLOR=#ff00ff]"The program's residence directory:"[/color] 
  [COLOR=#008080]call[/color] getdir()
[COLOR=#a020f0]end program[/color] get_program_dir

Then I compiled separately C++, fortran code and linked *.o files together into one executable
Code:
c:\00_mikrom\Work\fortran>g++ -c get_exe_path.c
c:\00_mikrom\Work\fortran>gfortran -c get_program_dir.f95
c:\00_mikrom\Work\fortran>gfortran get_exe_path.o get_program_dir.o -o get_program_dir -lstdc++

Now when I call it from the directory where I originally created it and where I'm sitting now I get this directory.
When I copy the executable [tt]get_program_dir.exe[/tt] to my network drive into the folder [tt]U:\fortran\deniall\[/tt] and call it from my home directory I get the directory path where the fortran EXE currently resides:
Code:
c:\00_mikrom\Work\fortran>get_program_dir.exe
 The program's residence directory:
c:\00_mikrom\Work\fortran

c:\00_mikrom\Work\fortran>U:\fortran\deniall\get_program_dir.exe
 The program's residence directory:
U:\fortran\deniall

So the program executable really prints the directory where it currently resides.
Try it.
 
Many thanks, Mikrom.[&nbsp;] That looks like it is doing exactly what I want.

However I am currently on the outer edges of civilisation, doing farm labour to help a friend harvest his crop.[&nbsp;] There is no internet, and I can only access the e-world using my mobile phone's feeble and intermittent mobile signal.[&nbsp;] So I won't be able to try to implement your solution for another fortnight or so.

One further thing.[&nbsp;] I don't have a C++ compiler, and I have never used any form of C before.[&nbsp;] Any chance you could send me "get_exe_path.o" as an attachment?

Again, many thanks.

--------------

As a PS, allow me to explain why I want this capability.[&nbsp;] The program I am working on produces a text file as its principal output.[&nbsp;] It makes certain assumptions about how the user might want this file to be formatted:[&nbsp;] page length; page width; standardised page heading information; output to be included; output to be explicitly excluded; etc.[&nbsp;] The program also looks for a small "configuration file" that the user can create, via which some of these assumptions can be changed.[&nbsp;] At present, the program looks for this configuration file in the current working directory only, where it will reside along with the user's input data file.[&nbsp;] I envisage a scenario where a company that uses the program might decide upon a standardised configuration file, yet on some particular projects might wish to deviate from this.[&nbsp;] The way I hope to allow this would have the company store its corporate configuration file alongside the .EXE file, both in some read-only directory somewhere on the corporate network.[&nbsp;] If some specific project requires a slightly different configuration, then the actual users can create a different configuration file that they store in the directory that contains their data files, the directory FROM WHICH they run the .EXE file.

So when the program is run it looks first in the "current directory" for a configuration file, and if it finds one it uses it then gets on with the job.[&nbsp;] If it doesn't find one there it looks in the directory in which the .EXE file resides, and uses that one.[&nbsp;] If it cannot find one there it simply runs with its inbuilt default configuration.

Clear as mud, eh?
 
Hi Deniall,

Here I uploaded the file [tt]get_exe_path.o[/tt] as image:
[URL unfurl="true"]https://res.cloudinary.com/engineering-com/raw/upload/v1649662694/tips/get_exe_path_grukgi.o[/url]
It was renamed by uploader, so after downloading, rename it to its original name.
Try to link it with the fortran code using the instructions I provided above.
Unfortunatelly if you have very different version of gfortran linking may not work.
I compiled it using gcc and gfortran versions 8.1.0 which are included in the Code::Blocks installation package [tt]codeblocks-20.03mingw-nosetup.zip[/tt] available here:
 
Thanks (again), Mikrom.

I tried what you sent me, but the linking step gave an error:
get_exe_path.o: file not recognized: File format not recognized
So there must be some sort of incompatibility between the compiler and the C++ object file you uploaded for me.

I think I am using GCC version 5.1.0, although I am deducing this from the Fortran User Manual that came with the package.[&nbsp;] I downloaded the compiler about a month ago, and merely selected what I thought looked the best package at the time.

I will try again in a couple of weeks, but I cannot justify putting a large amount of effort into achieving a feature that is really only peripheral to my program's main purpose.[&nbsp;] Neither can I justify asking you for further assistance:[&nbsp;] you have already been very generous with your time and your grey matter.

 
on the command line type
Code:
gfortran --version
and you will see what version you have.
Isn't gcc part of your gfortran package? Check it with:
Code:
gcc --version


 
Hi Deniall,
It seems to be very exciting. Say it finally: Have you tried it? Does it work or doesn't it?
 
Thanks for your persistence with this confused newbie, Mikrom.

I have tried the alternative version of get_exe_path.o that you sent me.[&nbsp;] It seemed to get a bit further, but only a bit.[&nbsp;] That --version trick you told me about informs me that both my GFortran and my GCC are version 6.3.0.

Here, in a Code Box, is the CMD-window dialogue between GFortran and me.[&nbsp;] "Q:\BELF>" is the command prompt (with Q: being a logical drive mapping I use to lessen the amount of typing I need to do). You will notice that the problems seem to begin when GFortran takes offence with the "-lstdc++", saying that it "cannot be found".[&nbsp;] So I removed it and tried again, but that seemed to make things worse.

Code:
Q:\BELF>Type get_program_dir.for
      Program get_program_dir
      write(*,*)"The program's residence directory:"
      call getdir()
      call exit
      end

Q:\BELF>GFortran  -c  get_program_dir.for

Q:\BELF>GFortran get_exe_path.o get_program_dir.o -o get_program_dir -lstdc++
d:/rmn/z_others/rmndev/gnu_fortran/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lstdc++
collect2.exe: error: ld returned 1 exit status

Q:\BELF>
Q:\BELF>REM  Try again with out the troublesome "-lstdc++" bit.

Q:\BELF>GFortran get_exe_path.o get_program_dir.o -o get_program_dir
get_exe_path.o:get_exe_path.c:(.text+0x12): undefined reference to `__gxx_personality_sj0'
get_exe_path.o:get_exe_path.c:(.text+0x40): undefined reference to `_Unwind_SjLj_Register'
get_exe_path.o:get_exe_path.c:(.text+0x4a): undefined reference to `std::allocator<char>::allocator()'
get_exe_path.o:get_exe_path.c:(.text+0x93): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned int, std::allocator<char> const&)'
   ...   h e a p s   m o r e   m e s s a g e s   o m i t t e d   ...
get_exe_path.o:get_exe_path.c:(.text+0x24f): undefined reference to `_Unwind_SjLj_Unregister'
get_exe_path.o:get_exe_path.c:(.text+0x26a): undefined reference to `std::ios_base::Init::~Init()'
get_exe_path.o:get_exe_path.c:(.text+0x28b): undefined reference to `std::ios_base::Init::Init()'
collect2.exe: error: ld returned 1 exit status

Q:\BELF>
 
GFortran is still displeased with the "-lstdc++" bit, although I think the resulting blizzard of error messages is slightly different.[&nbsp;] See below.

As I said in an earlier reply, this problem is not all that important to me in my overall scheme of things.[&nbsp;] Both my program and I can live without this issue being solved.[&nbsp;] I have already taken up a lot of your very helpful time, so please do not feel under any compunction to continue helping me.

Code:
Q:\BELF>

Q:\BELF>GFortran get_exe_path.o get_program_dir.o -o get_program_dir
get_exe_path.o:get_exe_path.c:(.text+0x10): undefined reference to `std::allocator<char>::allocator()'
get_exe_path.o:get_exe_path.c:(.text+0x4f): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned int, std::allocator<char> const&)'
get_exe_path.o:get_exe_path.c:(.text+0x5c): undefined reference to `std::allocator<char>::~allocator()'
get_exe_path.o:get_exe_path.c:(.text+0x6a): undefined reference to `std::allocator<char>::~allocator()'
get_exe_path.o:get_exe_path.c:(.text+0x9b): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find_last_of(char const*, unsigned int) const'
get_exe_path.o:get_exe_path.c:(.text+0xc0): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::substr(unsigned int, unsigned int) const'
get_exe_path.o:get_exe_path.c:(.text+0xfa): undefined reference to `std::cout'
get_exe_path.o:get_exe_path.c:(.text+0xff): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
get_exe_path.o:get_exe_path.c:(.text+0x10f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
get_exe_path.o:get_exe_path.c:(.text+0x119): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
get_exe_path.o:get_exe_path.c:(.text+0x123): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
get_exe_path.o:get_exe_path.c:(.text+0x131): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
get_exe_path.o:get_exe_path.c:(.text+0x13f): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
get_exe_path.o:get_exe_path.c:(.text+0x15f): undefined reference to `std::ios_base::Init::~Init()'
get_exe_path.o:get_exe_path.c:(.text+0x180): undefined reference to `std::ios_base::Init::Init()'
get_exe_path.o:get_exe_path.c:(.eh_frame+0x13): undefined reference to `__gxx_personality_v0'
collect2.exe: error: ld returned 1 exit status

Q:\BELF>
 
It must be linked with the option -lstdc++, otherwise it would not work.

Trying to use the option -lstdc++ you got this error
Code:
Q:\BELF>GFortran get_exe_path.o get_program_dir.o -o get_program_dir -lstdc++
d:/rmn/z_others/rmndev/gnu_fortran/mingw/bin/../lib/gcc/mingw32/6.3.0/../../../../mingw32/bin/ld.exe: cannot find -lstdc++
collect2.exe: error: ld returned 1 exit status

It means that you don't have libstdc++ present in your fortran distribution in the directory
d:/rmn/z_others/rmndev/gnu_fortran/mingw/lib/gcc/mingw32/6.3.0/

I upload you two files from my MinGW 6.3.0 version: libstdc++.a and libstdc++.dll.a

Download both, copy them in your directory
d:/rmn/z_others/rmndev/gnu_fortran/mingw/lib/gcc/mingw32/6.3.0/
and try to link with the option -lstdc++.
If it does not help, you can delete both files.

[URL unfurl="true"]https://res.cloudinary.com/engineering-com/raw/upload/v1649834138/tips/libstdc_ttdm4n.a[/url]

[URL unfurl="true"]https://res.cloudinary.com/engineering-com/raw/upload/v1649834162/tips/libstdc_.dll_dkummw.a[/url]
 
With my MinGW 6.3.0 i have this installer
2022-04-13_09h26_22_pmn9xc.png


If you have it too, you can install the c++ compiler additionally
2022-04-13_09h28_57_prhcyh.png
 
I thought about, why to use such a ballast as C++ for this simple task.
To get rid of libstdc++ i rewrote all from C++ in C:

get_exe_dir.c
Code:
[COLOR=#0000ff]/*[/color]
[COLOR=#0000ff]compile:[/color]
[COLOR=#0000ff]  gcc -c get_exe_dir.c[/color]
[COLOR=#0000ff]  gfortran -c get_program_dir.f95[/color]
[COLOR=#0000ff]  gfortran get_exe_dir.o get_program_dir.o -o get_program_dir[/color]
[COLOR=#0000ff]*/[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<stdio.h>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<string.h>[/color]
[COLOR=#a020f0]#include [/color][COLOR=#ff00ff]<windows.h>[/color]

[COLOR=#2e8b57][b]char[/b][/color] *get_exe_dir([COLOR=#2e8b57][b]void[/b][/color]);
[COLOR=#2e8b57][b]void[/b][/color] getdir_();

[COLOR=#2e8b57][b]char[/b][/color] *get_exe_dir()
{
    [COLOR=#2e8b57][b]int[/b][/color] exe_path_length, last_backslash;
    [COLOR=#2e8b57][b]char[/b][/color] *exe_path;
    [COLOR=#0000ff]// static does that the string will be permanently[/color]
    [COLOR=#0000ff]// allocated in the data segment of the program[/color]
    [COLOR=#2e8b57][b]static[/b][/color] [COLOR=#2e8b57][b]char[/b][/color] *result;

    [COLOR=#0000ff]// allocate memory for string[/color]
    exe_path = ([COLOR=#2e8b57][b]char[/b][/color] *) malloc(MAX_PATH * [COLOR=#804040][b]sizeof[/b][/color]([COLOR=#2e8b57][b]char[/b][/color]));

    exe_path_length = GetModuleFileName([COLOR=#ff00ff]NULL[/color], exe_path, MAX_PATH);

    [COLOR=#0000ff]// find last backslash[/color]
    last_backslash = [COLOR=#ff00ff]0[/color];
    [COLOR=#804040][b]for[/b][/color] ([COLOR=#2e8b57][b]int[/b][/color] i = [COLOR=#ff00ff]0[/color]; i < exe_path_length && exe_path[i] != [COLOR=#6a5acd]'\0'[/color]; i++) {
        [COLOR=#804040][b]if[/b][/color] (exe_path[i] == [COLOR=#6a5acd]'\\'[/color]) {
            last_backslash = i;
        }
    }

    [COLOR=#0000ff]// allocate memory for resulting string[/color]
    result = ([COLOR=#2e8b57][b]char[/b][/color] *) malloc(last_backslash * [COLOR=#804040][b]sizeof[/b][/color]([COLOR=#2e8b57][b]char[/b][/color]));

    strncpy(result, exe_path, last_backslash);
    result[last_backslash] = [COLOR=#6a5acd]'\0'[/color];

    [COLOR=#804040][b]return[/b][/color] result;
}

[COLOR=#2e8b57][b]void[/b][/color] getdir_()
{
    printf([COLOR=#ff00ff]"[/color][COLOR=#6a5acd]%s[/color][COLOR=#6a5acd]\n[/color][COLOR=#ff00ff]"[/color], get_exe_dir());
}

[COLOR=#0000ff]/*[/color]
[COLOR=#0000ff]int main()[/color]
[COLOR=#0000ff]{[/color]
[COLOR=#0000ff]    getdir_();[/color]
[COLOR=#0000ff]}[/color]
[COLOR=#0000ff]*/[/color]

The fortran source is the same - i changed only comment how to compile it

get_program_dir.f95
Code:
[COLOR=#0000ff]!compile:[/color]
[COLOR=#0000ff]!  gcc -c get_exe_dir.c[/color]
[COLOR=#0000ff]!  gfortran -c get_program_dir.f95[/color]
[COLOR=#0000ff]!  gfortran get_exe_dir.o get_program_dir.o -o get_program_dir[/color]
[COLOR=#a020f0]program[/color] get_program_dir
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color])[COLOR=#ff00ff]"The program's residence directory:"[/color] 
  [COLOR=#008080]call[/color] getdir()
[COLOR=#a020f0]end program[/color] get_program_dir

Now we can build the executable using these commands:
Code:
> gcc -c get_exe_dir.c
> gfortran -c get_program_dir.f95
> gfortran get_exe_dir.o get_program_dir.o -o get_program_dir

The resulting exe has 40 kB, the previous exe which was build with C++ standard library has 380 kB.

Attached is the file get_exe_dir.o for the MinGW gcc/gfortran version 6.3.0
[URL unfurl="true"]https://res.cloudinary.com/engineering-com/raw/upload/v1649847612/tips/get_exe_dir_qhuy7d.o[/url]
 
Finally I found fortran solution (without need to program something in C) posted in comp.lang.fortran here:

wintest.f95
Code:
[COLOR=#a020f0]module[/color] Win32
  [COLOR=#a020f0]use[/color] [COLOR=#008080]ISO_C_BINDING[/color]
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]private[/b][/color]

  [COLOR=#2e8b57][b]public[/b][/color] GetCurrentDirectory
  [COLOR=#a020f0]interface[/color]
    [COLOR=#a020f0]function[/color] GetCurrentDirectory(nBufferLength, lpBuffer) [COLOR=#804040][b]&[/b][/color]
    [COLOR=#2e8b57][b]bind[/b][/color](C,[COLOR=#804040][b]Name[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'GetCurrentDirectoryA'[/color])
      [COLOR=#a020f0]use[/color] [COLOR=#008080]ISO_C_BINDING[/color]
      [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]NONE[/b][/color]
      [COLOR=#0000ff]!GCC$ ATTRIBUTES STDCALL :: GetCurrentDirectory[/color]
      [COLOR=#2e8b57][b]integer[/b][/color]([COLOR=#008080]C_LONG[/color]) GetCurrentDirectory
      [COLOR=#2e8b57][b]integer[/b][/color]([COLOR=#008080]C_LONG[/color]),[COLOR=#2e8b57][b]value[/b][/color] :: nBufferLength
      [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]kind[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#008080]C_CHAR[/color]) lpBuffer([COLOR=#804040][b]*[/b][/color])
    [COLOR=#a020f0]end function[/color] GetCurrentDirectory
  [COLOR=#a020f0]end interface[/color]

  [COLOR=#2e8b57][b]public[/b][/color] GetModuleFileName
  [COLOR=#a020f0]interface[/color]
    [COLOR=#a020f0]function[/color] GetModuleFileName(hModule, lpFileName, nSize) [COLOR=#804040][b]&[/b][/color]
    [COLOR=#2e8b57][b]bind[/b][/color](C,[COLOR=#804040][b]Name[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'GetModuleFileNameA'[/color])
      [COLOR=#a020f0]use[/color] [COLOR=#008080]ISO_C_BINDING[/color]
      [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]NONE[/b][/color]
      [COLOR=#0000ff]!GCC$ ATTRIBUTES STDCALL :: GetModuleFileName[/color]
      [COLOR=#2e8b57][b]integer[/b][/color]([COLOR=#008080]C_LONG[/color]) GetModuleFileName
      [COLOR=#2e8b57][b]integer[/b][/color]([COLOR=#008080]C_INTPTR_T[/color]), [COLOR=#2e8b57][b]value[/b][/color] :: hModule
      [COLOR=#2e8b57][b]character[/b][/color]([COLOR=#2e8b57][b]kind[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#008080]C_CHAR[/color]) lpFileName([COLOR=#804040][b]*[/b][/color])
      [COLOR=#2e8b57][b]integer[/b][/color]([COLOR=#008080]C_LONG[/color]), [COLOR=#2e8b57][b]value[/b][/color] :: nSize
    [COLOR=#a020f0]end function[/color] GetModuleFileName
  [COLOR=#a020f0]end interface[/color]
[COLOR=#a020f0]end module[/color] Win32

[COLOR=#a020f0]program[/color] test
  [COLOR=#a020f0]use[/color] Win32
  [COLOR=#a020f0]use[/color] [COLOR=#008080]ISO_C_BINDING[/color]
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#2e8b57][b]integer[/b][/color]([COLOR=#008080]C_LONG[/color]) b
  [COLOR=#2e8b57][b]character[/b][/color] StringA[COLOR=#804040][b]*[/b][/color]([COLOR=#ff00ff]255[/color])

  b [COLOR=#804040][b]=[/b][/color] GetCurrentDirectory([COLOR=#008080]len[/color](StringA),StringA)
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],b
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]' Current Dir: '[/color][COLOR=#804040][b]//[/b][/color]StringA([COLOR=#ff00ff]1[/color]:b)

  b [COLOR=#804040][b]=[/b][/color] GetModuleFileName([COLOR=#ff00ff]0_C_INTPTR_T[/color],StringA,[COLOR=#008080]len[/color](StringA))
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],b
  [COLOR=#804040][b]print[/b][/color] [COLOR=#804040][b]*[/b][/color],[COLOR=#ff00ff]' Current ExeName: '[/color][COLOR=#804040][b]//[/b][/color]StringA([COLOR=#ff00ff]1[/color]:b)
[COLOR=#a020f0]end program[/color] test

After compilling it with
Code:
>gfortran wintest.f95 -o wintest

it works
2022-04-13_13h42_35_vbwbb5.png
 
Mikrom.
I have successfully implemented your 13Apr22@11:02 approach, and it works exactly as you indicated.[&nbsp;] I will not be able to explore it any further for a few days, because (as I said a few days ago) I am "on the outer edges of civilisation".[&nbsp;] Once my walnut-picking sojourn is over I will get back to it, explore it further, and utilise it in the program I am developing.
Many, many, thanks for all your help.
 
Hi Deniall,
So your problem has finally been solved. Wish you all the best.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top