Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28457 Discussions

Writing to File Whose Path Changes

durisinm
Novice
1,028 Views
I maintain an in-house (mostly) Fortran application that runs on VMS, Windows, and IRIX. At the end of a run the application opens a file and writes information about the date and time it was run, who ran it, and so on. Most of the source code is the same for all three versions; the OS-dependent parts have been pretty well isolated.

The VMS version uses a logical name for the file in the code. I can change the definition of the logical if necessary without having to modify the code.

The Windows version has the file name and path hard coded. A company mandate about security forced the location of the file to change, and now there is an error every time the application tries to open the file. The application still runs, but we're losing our usage information.

Can I replace the hard-coded file name and path in the Windows version with a system environment variable to give that version the same capability to point to a different file like the VMS version does? If not, then is there something else I can do to accomplish this?

Mike
0 Kudos
14 Replies
Steven_L_Intel1
Employee
1,028 Views
I can suggets two approaches.

1. Don't use a FILE= keyword and define the environment variable FORTn, where n is the unit number, to point to the file.

2. Precede the OPEN with a call to GETENV that retrieves the value of your defined environment variable and use the result in the OPEN call.

Steve
0 Kudos
TimP
Honored Contributor III
1,028 Views
Certainly, you should be able to use a getenv call to read an environment variable. See the library documentation.
0 Kudos
durisinm
Novice
1,028 Views
Thanks for those suggestions, guys.

I thought about this a little more and realized that I hadn't considered something. A system logical name on a VMS system will apply to all users of that system unless a user overrides it by defining his own process or job logical with the same name. A Windows environment variable, no matter whether it's a user or system variable, will apply to only the user of one computer.

This next released version of this application will be running on Windows XP computers, and I can create an installation program for it that sets the environment variable to the correct value. If the location of the file changes, though, I don't think that I can change the value of the variable myself. I'll have to do something like send out a message to the users with instructions on how to make the change or distribute a program that they would run to make the change for them. Are there any other alternatives?

Mike
0 Kudos
isn-removed200637
1,028 Views
One method occurs to me.
I assume all your users will use the same batch file to start your application.
Create a batch file which starts your application and include the latest file+path as an argument on the command line. Put the batch file in the 'system' folder, or some folder that is in everyone's path.
Rewrite your application to use GETARG to get the filename from the command line. Use the filename in your OPEN statement.
Edit the batch file whenever you need to change the file location.
Alternatively, write a small application to do this for you, giving the new file+path to it as an argument. This small aplication could write the batch file for you and copy it to the system folder.
Then all you need do is rerun this small application each time the file location is changed.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,028 Views
Mike, I didn't follow the rest of the thread carefully, but you (the setup program) could place the file in a folder which is supposed to be read/writeable for all users. See ShGetSpecialFolderLocation API -- CSIDL_APPDATA looks like the best candidate. (Usually, on Win2000 that should be C:Documents and SettingsAll UsersApplication Data, but I didn't test it, and the docs are a bit vague.) In this way, there's no need to cope with environment variables.

Jugoslav
0 Kudos
durisinm
Novice
1,028 Views
After reading the most recent replies it seems that I wasn't specific enough in my original posts. The file that all the application users need to access isn't located on their individual computers; it's a single common file located on a network share with permissions that allow anyone to write to it.

Another piece of information is that the application uses a console interface. Users type commands into the console window and press the Enter key after each one to have it executed.

In response to Anthony's post, the application isn't started with a batch file. Users start the application by typing the name of the executable file.

The documentation on the SHGetSpecialFolderLocation routine Jugoslav mentioned states that it has been superseded by SHGetFolderLocation as of Windows 2000. My users will be running this application on Windows XP. All the CSIDL values for the nFolder parameter appear to refer to local files on a single computer, not files on a network share.

Mike
0 Kudos
isn-removed200637
1,028 Views
It is easy to write a batch file APPLICATION.BAT that runs APPLICATION.EXE
with a command line argument giving the location of the file in question. eg
@echo off
rem file: APPLICATION.BAT
rem function: to start  APPLICATION.EXE with DATAFILENAME as argument
rem fullpathap stands for the full path to the application executable
rem fullpathdat stands for the full path to the data file
fullpathapAPPLICATION.exe fullpathdatDATAFILENAME
IIRC, typing APPLICATION without extension on a command line will
run the BAT file with the name APPLICATION before trying APPLICATION.EXE.
Your users therefore only need have the .BAT file in
their path so that it is found when they type APPLICATION
then hit . You can keep the executable in another
place of your choice, along with your file. Just supply
the full [network] path with the application and the
data file name on the command line in the batch file
you distribute to all your users.
The above .BAT file contains only one important command,
to run the application.
This can just as easily be programmed as another
executable that issues the system command using the
command SYSTEMQQ to send a command string to the command
interpreter.
0 Kudos
durisinm
Novice
1,028 Views
Thank you to everyone for all your suggestions on what has turned out to be much more of an OS question than a Fortran one.

I still see a problem that I'll have to work out. A VMS system allows a change to a logical name that will affect multiple users sharing the same computer without the need to modify the Fortran code. Windows computers are fundamentally different because the vast majority of them are single-user systems. I can use the suggestions given above to isolate the name of a file from the Fortran code, but I don't see an easy way to push down a changed file name to all the individual computers if that becomes necessary. I can send messages to the users with instructions on how to manually do it, or I can send them an application that they could run to make the changes, but I can't do it independently from a central location. I guess I'll have to live with that.

Mike
0 Kudos
Steven_L_Intel1
Employee
1,028 Views
The closest equivalent to a VMS system logical name for Windows would be an entry in the registry, which is easy to change and straightforward to access from Fortran.

But typically for Windows users, you're dealing with multiple separate PCs connected to a network. In such cases, a network shared folder could be the best solution - if you need to change the location, you just redefine the share. The downside of this is that the server name has to remain fixed and you can point to a folder, not an individual file.

Steve
0 Kudos
tmcole
Beginner
1,028 Views
Mike,

I don't know if this is what you are looking for, but I always read in from what I call a "control file" the names of all input/output filenames into character variables. I then use these variables in the OPEN statements. This allows great flexibility in the specification of I/O filenames as well as compatability across all operating systems. You can also put in the option of interactively entering I/O filenames. Hope this helps.

Tom
0 Kudos
james1
Beginner
1,028 Views
Mike,

First, VMS logical names when it comes to filenames are more like environment variables than registry settings. In fact a while back I proposed to Steve that the Fortran RTL would be well served to automatically expand environment strings as the command interpreter does, however I don't know if that would ever become reality.

Next, it is important to know if you are targeting just the NT family or also 9X. Depending on how your network is arranged, it is actually quite simple to do the equivalent of a system-wide environment setting. How you actually do this depends NT vs 9X family and the security scheme (domain, workgroup) you are using.

James
0 Kudos
Steven_L_Intel1
Employee
1,028 Views
It's pretty easy to call the Win32 API routine ExpandEnvironmentStrings yourself. I'll let you in on a little secret - I did manage to sneak in to the compiler a call to ExpandEnvironmentStrings for INCLUDE filespecs - look for this in Intel Visual Fortran.

Note also that the CVF RTL will already expand environment variables of the form FORTn, where n is the unit number, if you omit FILE=.

Steve
0 Kudos
james1
Beginner
1,028 Views
Yes it is easy to call the Win32 routine, however if you have a lot of different OPENs in your code then either you end up with a bunch of

if OS is WIN32
call ExpandEnvironmentStrings (...)
else
expanded_filename = unexpanded_name
end if

OPEN (file=expanded_name, ...)

or

OPEN (file=TRIM(EXPAND_ROUTINE(unexpanded_name)), ...)

It would just be so pretty if we could have just a regular OPEN without the extras.

As for the INCLUDE filespect that is progress, thanks.

FORTn as a system environment variable seems a reasonable solution to the present case.

James
0 Kudos
durisinm
Novice
1,028 Views
I think I have all the raw input I need to craft a good solution. It's time for me to digest it and experiment with some of these suggestions.

I never fail to be impressed with the willingness to help and the quality of the suggestions that one can find in this forum. I am so glad that the world is filled with a lot of smart people who take the time to share their knowledge with others. Thanks a bunch.

Mike
0 Kudos
Reply