Skip to main content

Our many user sites have been using various 32-bit AcuGT runtimes with a variety of 32-bit Windows applications. Among those applications is the Adobe Reader, and recently Adobe is forcing an "upgrade" to their 64-bit version. When our applications attempt to launch Reader the runtime fails and returns a system code 2. (Installing 32-bit Foxit Reader is a good workaround.)

But in anticipation Looking to the future three questions::

1. Can we "correct" our applications to launch 64-bit applications? If not

2. Is the solution to use the 64-bit runtime? If so

3. Will the 64-bit runtime work with the 32-bit Windows applicaions?

My hope is that the answer to 1 is Yes. Any guidance will be gratefully appreciated.

Our many user sites have been using various 32-bit AcuGT runtimes with a variety of 32-bit Windows applications. Among those applications is the Adobe Reader, and recently Adobe is forcing an "upgrade" to their 64-bit version. When our applications attempt to launch Reader the runtime fails and returns a system code 2. (Installing 32-bit Foxit Reader is a good workaround.)

But in anticipation Looking to the future three questions::

1. Can we "correct" our applications to launch 64-bit applications? If not

2. Is the solution to use the 64-bit runtime? If so

3. Will the 64-bit runtime work with the 32-bit Windows applicaions?

My hope is that the answer to 1 is Yes. Any guidance will be gratefully appreciated.

This is pretty much a restriction of the Windows environment, 32-bit dlls can call other 32-bit dlls, and 64-bit dlls can call other 64-bit dlls. However, you cannot intermingle, 32-bit cannot call 64-bit, and 64-bit cannot call 32-bit. From more info - see articles about WoW64 like this: https://pvs-studio.com/en/blog/terms/0056/

1. You should be able to run your existing COBOL object file with the Acu 64 bit runtime. Any calls to an external program Adobe, Access, Excel) (including Windows dlls) those applications and dlls need to be 64 bit. 

One option (and I'm not trying to sell a future version) is that Acu 10.5.0 (GA mid 2022) will have both a 32-bit thin client and a 64-bit thin client. Since thin client is client side, the 32-bit Thin clients can run the program on the server and when that server program calls a "local" program (@display)  - the local program would be the 32-bit based one (like 32-bit Office Access). And the 64-bit Thin clients can run the program on the server and when that server program calls a "local" program - the local program would be the 64-bit based one (like 64-bit Office Access). 


Our many user sites have been using various 32-bit AcuGT runtimes with a variety of 32-bit Windows applications. Among those applications is the Adobe Reader, and recently Adobe is forcing an "upgrade" to their 64-bit version. When our applications attempt to launch Reader the runtime fails and returns a system code 2. (Installing 32-bit Foxit Reader is a good workaround.)

But in anticipation Looking to the future three questions::

1. Can we "correct" our applications to launch 64-bit applications? If not

2. Is the solution to use the 64-bit runtime? If so

3. Will the 64-bit runtime work with the 32-bit Windows applicaions?

My hope is that the answer to 1 is Yes. Any guidance will be gratefully appreciated.

Based on the description, it sounds like you're trying to run an out-of-process 64-bit program from a 32-bit program.  What Steve said is definitely true for in-process components: with complex, limited exceptions, in-process components like DLLs and controls must be the same "bitness" as the hosting process.  But using CALL SYSTEM to launch a separate .EXE with a command line, it shouldn't matter whether the target program is 32-bit or 64-bit.  It would seem to me that you'd simply have to invoke the 64-bit version of Acrobat, and the difference here is that it's located in "c:\\Program Files" instead of "c:\\Program Files (x86)". 

(It gets more complicated if you want to support Win32-only systems vs. Win64 system that run Win32 programs in the WOW32 subsystem -- but Win32-only systems are on their way out and Windows 11 doesn't even support them.)

If Acrobat being launched using DCOM out-of-process activation, then it gets much more complicated. There are activation options that determine whether a 32-bit or 64-bit instance is being created and which is preferred. If a 64-bit Acrobat DCOM server needs to communicate back to the 32-bit client (the COBOL program), it would be with a proxy/stub; I'd be surprised if Acrobat didn't support that. But as I said, it can quickly get complicated.

Still, if it's a simple Windows application being created with CALL SYSTEM, it shouldn't matter whether the target EXE is 32-bit or 64-bit. You just have to know where it is so you can launch it.


Based on the description, it sounds like you're trying to run an out-of-process 64-bit program from a 32-bit program.  What Steve said is definitely true for in-process components: with complex, limited exceptions, in-process components like DLLs and controls must be the same "bitness" as the hosting process.  But using CALL SYSTEM to launch a separate .EXE with a command line, it shouldn't matter whether the target program is 32-bit or 64-bit.  It would seem to me that you'd simply have to invoke the 64-bit version of Acrobat, and the difference here is that it's located in "c:\\Program Files" instead of "c:\\Program Files (x86)". 

(It gets more complicated if you want to support Win32-only systems vs. Win64 system that run Win32 programs in the WOW32 subsystem -- but Win32-only systems are on their way out and Windows 11 doesn't even support them.)

If Acrobat being launched using DCOM out-of-process activation, then it gets much more complicated. There are activation options that determine whether a 32-bit or 64-bit instance is being created and which is preferred. If a 64-bit Acrobat DCOM server needs to communicate back to the 32-bit client (the COBOL program), it would be with a proxy/stub; I'd be surprised if Acrobat didn't support that. But as I said, it can quickly get complicated.

Still, if it's a simple Windows application being created with CALL SYSTEM, it shouldn't matter whether the target EXE is 32-bit or 64-bit. You just have to know where it is so you can launch it.

Thank you Ewe. Our software is simple in this regard. We use CALL :"C$SYSTEM" to launch the .pdf program and if that produces an exception we then use CALL "C$RUN". I assume that is what you mean by CALL SYSTEM. The problem happens before we get to the CALL.

We have a standard source routine Z-LAUNCH-PROGRAM-FOR-FILE-NAME that we use for all types of registered extensions. The source is several years old and has always worked for all registered extensions until the 64-bit Reader. Specifically when 64-bit Adobe Reader is installed and QUERY-SUBKEY value is “.pdf” and FILE-NAME is the full pathname of the pdf file, the second PERFORM Z-GET-QUERY returns a value of 2. I have no idea what the 2 means. Perhaps I can tweak something simple to make it work.

Again thanks for your help.

 

******************************************************************

 Z-LAUNCH-PROGRAM-FOR-FILE-NAME.

*------------------------------

** Input:  QUERY-SUBKEY  - File suffix, e.g. .csv, .bmp, .txt

**         FILE-NAME

** Output: QUERY-STATUS  - 0 if successful

 

     PERFORM Z-GET-QUERY-ANSWER

     IF QUERY-ANSWER NOT > SPACE

         MOVE 1                  TO QUERY-STATUS

     END-IF.

 

     IF QUERY-STATUS NOT = 0

         MOVE "No registry found for file type"

                                 TO S-MESSAGE-AREA

         MOVE QUERY-SUBKEY       TO S-MESSAGE-PART-1

         MOVE "- Error status"

                                 TO S-MESSAGE-PART-2

         MOVE QUERY-STATUS       TO S-MESSAGE-NBR-3

         PERFORM Z-ERROR-DIALOG

     ELSE

         MOVE QUERY-ANSWER       TO S-ALPHA

         MOVE MAX-S-ALPHA-CHAR   TO K

         IF S-ALPHA NOT > SPACE

             MOVE 1              TO K

         ELSE

             PERFORM UNTIL S-CHAR(K) > SPACE

                 SUBTRACT 1        FROM K

             END-PERFORM

         END-IF

         MOVE SPACE              TO QUERY-SUBKEY

         STRING S-ALPHA(1:K)             DELIMITED BY SIZE

               "\\shell\\open\\command"     DELIMITED BY SIZE

                               INTO QUERY-SUBKEY

         END-STRING

         MOVE SPACE              TO QUERY-ANSWER

         PERFORM Z-GET-QUERY-ANSWER

         IF QUERY-STATUS NOT = 0

             MOVE "Registry look up failed"

                                 TO S-MESSAGE-AREA

             MOVE "- Error status"

                                 TO S-MESSAGE-PART-1

             MOVE QUERY-STATUS   TO S-MESSAGE-NBR-2

             PERFORM Z-ERROR-DIALOG

         ELSE

 

[Snip}

 

******************************************************************

 Z-GET-QUERY-ANSWER.

*------------------

** Input:  QUERY-SUBKEY

** Output: QUERY-ANSWER

**         QUERY-STATUS

     MOVE 0                      TO QUERY-STATUS

     MOVE MAX-QUERY-ANSWER-SIZE  TO QUERY-SIZE

     CALL "REG_QUERY_VALUE"   USING HKEY_CLASSES_ROOT

                                    QUERY-ANSWER

                                    QUERY-SIZE

                                    QUERY-SUBKEY

                             GIVING QUERY-STATUS

     ON EXCEPTION

         MOVE 1                  TO QUERY-STATUS

     END-CALL.


Thank you Ewe. Our software is simple in this regard. We use CALL :"C$SYSTEM" to launch the .pdf program and if that produces an exception we then use CALL "C$RUN". I assume that is what you mean by CALL SYSTEM. The problem happens before we get to the CALL.

We have a standard source routine Z-LAUNCH-PROGRAM-FOR-FILE-NAME that we use for all types of registered extensions. The source is several years old and has always worked for all registered extensions until the 64-bit Reader. Specifically when 64-bit Adobe Reader is installed and QUERY-SUBKEY value is “.pdf” and FILE-NAME is the full pathname of the pdf file, the second PERFORM Z-GET-QUERY returns a value of 2. I have no idea what the 2 means. Perhaps I can tweak something simple to make it work.

Again thanks for your help.

 

******************************************************************

 Z-LAUNCH-PROGRAM-FOR-FILE-NAME.

*------------------------------

** Input:  QUERY-SUBKEY  - File suffix, e.g. .csv, .bmp, .txt

**         FILE-NAME

** Output: QUERY-STATUS  - 0 if successful

 

     PERFORM Z-GET-QUERY-ANSWER

     IF QUERY-ANSWER NOT > SPACE

         MOVE 1                  TO QUERY-STATUS

     END-IF.

 

     IF QUERY-STATUS NOT = 0

         MOVE "No registry found for file type"

                                 TO S-MESSAGE-AREA

         MOVE QUERY-SUBKEY       TO S-MESSAGE-PART-1

         MOVE "- Error status"

                                 TO S-MESSAGE-PART-2

         MOVE QUERY-STATUS       TO S-MESSAGE-NBR-3

         PERFORM Z-ERROR-DIALOG

     ELSE

         MOVE QUERY-ANSWER       TO S-ALPHA

         MOVE MAX-S-ALPHA-CHAR   TO K

         IF S-ALPHA NOT > SPACE

             MOVE 1              TO K

         ELSE

             PERFORM UNTIL S-CHAR(K) > SPACE

                 SUBTRACT 1        FROM K

             END-PERFORM

         END-IF

         MOVE SPACE              TO QUERY-SUBKEY

         STRING S-ALPHA(1:K)             DELIMITED BY SIZE

               "\\shell\\open\\command"     DELIMITED BY SIZE

                               INTO QUERY-SUBKEY

         END-STRING

         MOVE SPACE              TO QUERY-ANSWER

         PERFORM Z-GET-QUERY-ANSWER

         IF QUERY-STATUS NOT = 0

             MOVE "Registry look up failed"

                                 TO S-MESSAGE-AREA

             MOVE "- Error status"

                                 TO S-MESSAGE-PART-1

             MOVE QUERY-STATUS   TO S-MESSAGE-NBR-2

             PERFORM Z-ERROR-DIALOG

         ELSE

 

[Snip}

 

******************************************************************

 Z-GET-QUERY-ANSWER.

*------------------

** Input:  QUERY-SUBKEY

** Output: QUERY-ANSWER

**         QUERY-STATUS

     MOVE 0                      TO QUERY-STATUS

     MOVE MAX-QUERY-ANSWER-SIZE  TO QUERY-SIZE

     CALL "REG_QUERY_VALUE"   USING HKEY_CLASSES_ROOT

                                    QUERY-ANSWER

                                    QUERY-SIZE

                                    QUERY-SUBKEY

                             GIVING QUERY-STATUS

     ON EXCEPTION

         MOVE 1                  TO QUERY-STATUS

     END-CALL.

I'm from the RM/COBOL world and CALL SYSTEM is the RM equivalent (also implemented in ACU). Sorry for the confusion. 

I'll describe below how I'd approach this problem.  However: I have not tried this and have no idea if it would work or if there is something in the internal REG_OPEN_KEY_EX implementation that would prevent this from working.  Also, I don't have a 64-bit Acrobat available so I can't even look at the registry. Note that if you have a 32-bit Acrobat installed, the 64-bit registry will show the file association because of registry reflection. I think someone could dedicate an entire career to understanding how the registry works.

(BTW, if you want to look at the registry in the way that the 32-bit ACU program "sees" the registry, close any open registry editors and run this command to start the registry editor: C:\\WINDOWS\\SYSWOW64\\REGEDIT.EXE.  You'll notice that this registry entry: Computer\\HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node does not exist as that's the place in the 64-bit registry that the 32-bit registry lives.)

All that said: It looks like you're tracking down the installed Acrobat executable using the PDF file association. 

32-bit applications query the 32-bit registry and cannot see the 64-bit registry without a special option: KEY_WOW64_64KEY. That value (256) must be inclusive-OR'd into the SAM-DESIRED parameter to REG_OPEN_KEY_EX to get a registry handle. Then you should be able to use REG_QUERY_VALUE like right now but it will be reading the 64-bit registry instead of the 32-bit registry.

If this works (and, again, I haven't tried it), after what you're doing now (just in case there's a 32-bit Acrobat that could be used), you'd call REG_OPEN_KEY_EX with the standard SAM-DESIRED options along with KEY_WOW64_64KEY, then call REG_QUERY_VALUE  to find the 64-bit file association, then REG_CLOSE_KEY to free resources.

The ACUGUI.DEF file doesn't define KEY_WOW64_64KEY.  The value is 256 -- you might want to raise an enhancement request to add official support to ACU for this Windows "feature".  The reverse option exists for 64-bit programs to read the 32-bit registry as if they were a 32-bit app.

Again, no guarantees, but the above is what I'd try.

Here is more information on alternate registry views, which is what you need to look at the 64-bit registry from a 32-bit app: https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view


I'm from the RM/COBOL world and CALL SYSTEM is the RM equivalent (also implemented in ACU). Sorry for the confusion. 

I'll describe below how I'd approach this problem.  However: I have not tried this and have no idea if it would work or if there is something in the internal REG_OPEN_KEY_EX implementation that would prevent this from working.  Also, I don't have a 64-bit Acrobat available so I can't even look at the registry. Note that if you have a 32-bit Acrobat installed, the 64-bit registry will show the file association because of registry reflection. I think someone could dedicate an entire career to understanding how the registry works.

(BTW, if you want to look at the registry in the way that the 32-bit ACU program "sees" the registry, close any open registry editors and run this command to start the registry editor: C:\\WINDOWS\\SYSWOW64\\REGEDIT.EXE.  You'll notice that this registry entry: Computer\\HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node does not exist as that's the place in the 64-bit registry that the 32-bit registry lives.)

All that said: It looks like you're tracking down the installed Acrobat executable using the PDF file association. 

32-bit applications query the 32-bit registry and cannot see the 64-bit registry without a special option: KEY_WOW64_64KEY. That value (256) must be inclusive-OR'd into the SAM-DESIRED parameter to REG_OPEN_KEY_EX to get a registry handle. Then you should be able to use REG_QUERY_VALUE like right now but it will be reading the 64-bit registry instead of the 32-bit registry.

If this works (and, again, I haven't tried it), after what you're doing now (just in case there's a 32-bit Acrobat that could be used), you'd call REG_OPEN_KEY_EX with the standard SAM-DESIRED options along with KEY_WOW64_64KEY, then call REG_QUERY_VALUE  to find the 64-bit file association, then REG_CLOSE_KEY to free resources.

The ACUGUI.DEF file doesn't define KEY_WOW64_64KEY.  The value is 256 -- you might want to raise an enhancement request to add official support to ACU for this Windows "feature".  The reverse option exists for 64-bit programs to read the 32-bit registry as if they were a 32-bit app.

Again, no guarantees, but the above is what I'd try.

Here is more information on alternate registry views, which is what you need to look at the 64-bit registry from a 32-bit app: https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view

Uwe-

Thanks you again. You've given me a lot of new information. Urgent issues keep me from acting on it until next week. but I will get to it, and want you know that your help is very appreciated.


Our many user sites have been using various 32-bit AcuGT runtimes with a variety of 32-bit Windows applications. Among those applications is the Adobe Reader, and recently Adobe is forcing an "upgrade" to their 64-bit version. When our applications attempt to launch Reader the runtime fails and returns a system code 2. (Installing 32-bit Foxit Reader is a good workaround.)

But in anticipation Looking to the future three questions::

1. Can we "correct" our applications to launch 64-bit applications? If not

2. Is the solution to use the 64-bit runtime? If so

3. Will the 64-bit runtime work with the 32-bit Windows applicaions?

My hope is that the answer to 1 is Yes. Any guidance will be gratefully appreciated.

If all you need to do is to start the application that handles .pdf files, then the new 10.5.0 WIN$SHELLEXECUTE routine may be what you need. (This will also handle any registered extension, not just .pdf files.)

I assume that a 32-bit runtime would invoke the 64-bit Adobe Acrobat Reader in this case - we will be testing that.

For the more general question of launching 64-bit apps from a 32-bit runtime, what Uwe says is true - it should just work as long as you have the correct path for the 64-bit executable.


If all you need to do is to start the application that handles .pdf files, then the new 10.5.0 WIN$SHELLEXECUTE routine may be what you need. (This will also handle any registered extension, not just .pdf files.)

I assume that a 32-bit runtime would invoke the 64-bit Adobe Acrobat Reader in this case - we will be testing that.

For the more general question of launching 64-bit apps from a 32-bit runtime, what Uwe says is true - it should just work as long as you have the correct path for the 64-bit executable.

Randy-

Thanks for help. I look forward to upgrading to 10.5.0, but UBCC is still in the process of upgrading all our user installations to v10.2.1. Because they are not all there yet, all our application object is compiled in compatibility mode for the runtime v9.0.

This is curious: Our developers use v10.2.1, but one of our in house test workstations runs the v10.3.0 32bit runtime with our standard application object. That tester reports that it continues to call the 64bit Reader without error. (His reports are credible to me, so I discount the likelihood of user error.) I am a loss to explain why it works for him.


Randy-

Thanks for help. I look forward to upgrading to 10.5.0, but UBCC is still in the process of upgrading all our user installations to v10.2.1. Because they are not all there yet, all our application object is compiled in compatibility mode for the runtime v9.0.

This is curious: Our developers use v10.2.1, but one of our in house test workstations runs the v10.3.0 32bit runtime with our standard application object. That tester reports that it continues to call the 64bit Reader without error. (His reports are credible to me, so I discount the likelihood of user error.) I am a loss to explain why it works for him.

I'd take a good look at the registry on the machine that's succeeding. Look at the registry in 32 and 64-bit mode by launching the registry editor from C:\\WINDOWS\\SYSTEM32 for the 64-bit view, and from C:\\WINDOWS\\SYSWOW64 for the 32-bit view that ACU sees.   Also look at both HKLM and HKCU (current user).  There may be a difference that depends on how Acrobat was installed -- by the logon ID that's running it for both machine and current user or just current user, or by a separate administrator account that can only install machine-wide programs. 

If you have the appropriate skills in your staff, you could also consider simply writing a non-COBOL program in C/C++ that would launch Acrobat reader directly instead of through C$SYSTEM -- pretty much doing what WIN$SHELLEXECUTE does in 10.5. That's the approach that I would take, if the problem needs to be solved quickly.  There's nothing magical about calling such a function from COBOL.


I'd take a good look at the registry on the machine that's succeeding. Look at the registry in 32 and 64-bit mode by launching the registry editor from C:\\WINDOWS\\SYSTEM32 for the 64-bit view, and from C:\\WINDOWS\\SYSWOW64 for the 32-bit view that ACU sees.   Also look at both HKLM and HKCU (current user).  There may be a difference that depends on how Acrobat was installed -- by the logon ID that's running it for both machine and current user or just current user, or by a separate administrator account that can only install machine-wide programs. 

If you have the appropriate skills in your staff, you could also consider simply writing a non-COBOL program in C/C++ that would launch Acrobat reader directly instead of through C$SYSTEM -- pretty much doing what WIN$SHELLEXECUTE does in 10.5. That's the approach that I would take, if the problem needs to be solved quickly.  There's nothing magical about calling such a function from COBOL.

Uwe-

I finally found time to try to implement the dual-registry logic that you suggested. In preparation, on my 64-bit workstation I uninstalled Foxit (my workaround for opening .pdfs from our applications). Then I downloaded and installed Adobe Acrobat Reader DC. Not surprisingly according to the title bar it is again 64-bit, not 32-bit. But using the same 32-bit 10.2.1 runtime and our 9.0 compatible object I have no issues using to open .pdf files.  I.e. Our software seamlessly opens our pdfs with 64-bit Reader. I have been using it for ordinary development and testing, and so far I have not been able to reproduce the problem that inspired this thread. Therefore I cannot make testable changes to our applications. I am waiting for our other developer who had the same issue to do the reinstallation, but as of now my best guess is/was that the Adobe automatic enforced update is defective. Should the error reappear, I will try to correct it using your suggestions.

I regret having wasted everyone’s time on this issue.

Thanks,

Sal


Uwe-

I finally found time to try to implement the dual-registry logic that you suggested. In preparation, on my 64-bit workstation I uninstalled Foxit (my workaround for opening .pdfs from our applications). Then I downloaded and installed Adobe Acrobat Reader DC. Not surprisingly according to the title bar it is again 64-bit, not 32-bit. But using the same 32-bit 10.2.1 runtime and our 9.0 compatible object I have no issues using to open .pdf files.  I.e. Our software seamlessly opens our pdfs with 64-bit Reader. I have been using it for ordinary development and testing, and so far I have not been able to reproduce the problem that inspired this thread. Therefore I cannot make testable changes to our applications. I am waiting for our other developer who had the same issue to do the reinstallation, but as of now my best guess is/was that the Adobe automatic enforced update is defective. Should the error reappear, I will try to correct it using your suggestions.

I regret having wasted everyone’s time on this issue.

Thanks,

Sal

Thanks for following up.  Normally, if a 64-bit application is installed, it "shows through" to the 32-bit registry, so I would have expected it to work.  Also, there is only one setting for default apps in current user, and if it's not explicitly set, it is also redirected to the 32-bit or 64-bit application. This is really far too complicated and there really should be a tool that says "show me the registry as my application sees it".  It's entirely possible Adobe isn't getting this right, or left-over entries in the 32-bit registry for a now-deleted application could remain and be invalid.  There are just so many ways for application vendors to get this wrong.   Glad you got a fix.