odaniel
Posts: 10
Joined: Thu May 14, 2020 3:33 pm

Using a DLL to set APPDIR

I'm working on an installer that uses a standard DLL to determine the path of APPDIR bases on the location where the user is installing our application. The DLL checks the user's ip address to determine if the installation is being performed in our offices or our outside of our company network.

For an office setting, I want the installer use a predetermined location on the computer. However for all other situations, it uses a location in the user's AppData folder instead. So far the DLL is integrated into the install and works well. The issue I'm having is in determining when I can change APPDIR.

The DLL has an exported function that performs the ip address check and returns a folder path as a string. The DLL is also added as a temporary file.

I created 2 custom actions. The first calls the exported function in the DLL that returns the target path which I assign to a user property.

The second custom action. Sets the APPDIR property to the user property from the first action.

I've been having trouble determining when APPDIR should be set.

The sequence for the Install Stage is as follows (my custom actions are in bold)

Searches
Paths Resolution
Preparing
RemoveExistingProducts
Remove Resources
Call Function From DLL ( calls DLL function to get path and sets user property with return value )
SetProperty ( sets APPDIR to user property from above)
Add Resources
Finish Execution

What I end up with is the application executable installing to the default path I set for APPDIR in the project. However I also import values into an INI file which is also installed to APPDIR. But I see that INI file gets copied to the path I return from the DLL. In other words, the executable always gets copied to the hardcoded APPDIR value in the project but the INI file is copied to the path returned from the DLL function call.

It seems like that the program executable is copied before APPDIR is changed, but the INI file is copied (imported) after the value is changed.

if I move the 2 custom actions earlier, I get an error that the DLL can't be found. Again the DLL is a temporary file.

Also note that this is a minimal user interface. No dialogs. Just the progress bar displayed.

Any ideas on what is the best to accomplish the task of setting APPDIR from a DLL function call?
Catalin
Posts: 6596
Joined: Wed Jun 13, 2018 7:49 am

Re: Using a DLL to set APPDIR

Hello Daniel,

The folders from the project are resolved during the "CostFinalize" standard action.

The above standard action is part of the "Paths Resolution" action group (your project --> "Custom Actions" page).

For more information about standard actions, please have a look over the [urlhttps://www.advancedinstaller.com/user-guide/st ... tions.html]"Windows Installer Standard Actions"[/url] article.

Basically, if you want to change the value of the APPDIR property, you will need to do so before the "Path Resolution" action group. There are three ways of achieving this, depending on what your scenario is:

1. if the setup is run with full UI, you can add your custom action as a custom action without sequence. A custom action without sequence can be triggered from a UI control. For example, you can trigger this custom action from the "Next" button of your "FolderDlg" dialog.

WithoutSequence.png
WithoutSequence.png (204.08 KiB) Viewed 4541 times

2. if the setup is run with full UI, you can add the custom action as a custom action with sequence. To do so, simply add your custom action in the "Custom Actions" page --> "Wizard Dialogs Stage" --> before the "Paths Resolution" action group.

3. if the setup is run silently (no UI), we will need to add the custom action in the "Install Execution Stage", since the "Wizard Dialogs Stage" is skipped, as there is no UI displayed. Once again, the custom action should be added before the "Paths Resolution" action group.

Hope this helps.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
odaniel
Posts: 10
Joined: Thu May 14, 2020 3:33 pm

Re: Using a DLL to set APPDIR

Hi Catalin,

I have a minimal UI with only the progress bar shown.

If I place the custom action that calls the DLL function earlier (as you suggested before Paths Resolution), I get an error that the DLL cannot be found. I'm assuming that the installer has not extracted the DLL at this point in the process.

This is the set of actions I have for the Install Execution Stage. The custom action with the DLL function call is named GetTrlmAppPath. The SetProperty action is where I assign the property with the returned value to APPDIR.
actions.png
actions.png (20.52 KiB) Viewed 4540 times
This is the error I get when running the installer
error.png
error.png (5.2 KiB) Viewed 4540 times

Note that the DLL was added to the project as a temporary file.

How do I configure the DLL within the installer project so it is available for use before the Paths Resolution?

Thanks
Catalin
Posts: 6596
Joined: Wed Jun 13, 2018 7:49 am

Re: Using a DLL to set APPDIR

Hello Daniel,

I somehow overlooked this detail in your explanation. I am sorry about this.

Please note that temporary files are copied on the machine during the "CostFinalize" standard action (since this is the action that resolves the folders).

With that being said, please go to "Custom Actions" page --> right click on "Paths Resolution" --> "Show standard action" --> "Paths Resolution" --> click on "CostFinalize".

After doing so, please place your custom action right after the "CostFinalize" action.

Hope this helps.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
odaniel
Posts: 10
Joined: Thu May 14, 2020 3:33 pm

Re: Using a DLL to set APPDIR

HI Catalin,

Thank you for the fast reply. I made the changes but I'm still getting the error regarding the DLL not being found.

Here is the Install Execution Stage now with Cost Finalize shown.
costfinalize.png
costfinalize.png (18.55 KiB) Viewed 4535 times
I'm also including a screenshot of the details of the function call.

Under Execution Time, I selected Immediately but now I'm wondering if that might be part of the problem. Should it be deferred?
dllstdcall.png
dllstdcall.png (23.23 KiB) Viewed 4535 times
Thanks again
Catalin
Posts: 6596
Joined: Wed Jun 13, 2018 7:49 am

Re: Using a DLL to set APPDIR

Hello Daniel,

As you can see, the "Deferred" option is disabled. At that point where you scheduled the custom action, an action can only be of "Immediately" type.

I believe this might be related to the given path of the .DLL file. Could you please delete the:

Code: Select all

[TempFolder]installsupport.dll
and then input the square bracket character:

Code: Select all

[
and then, from the dropdown, select "File" --> "Windows Volume" --> "Temporary" --> select your .DLL file.

it should look similar to this:

[&dllName.dll]

Hope this helps.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
odaniel
Posts: 10
Joined: Thu May 14, 2020 3:33 pm

Re: Using a DLL to set APPDIR

Hi Catalin,

I made the change as you suggested. The DLL path now shows:

Code: Select all

[&installsupport.dll]
Unfortunately this resulted in a new error:
Failed to load. Error: The parameter is incorrect.
If anything else comes to mind, please let me know.

Thanks
Catalin
Posts: 6596
Joined: Wed Jun 13, 2018 7:49 am

Re: Using a DLL to set APPDIR

Hello Daniel,

Unfortunately, I can not say for sure why that happens.

Could you please give me some more details about how you created the .DLL file so I can further test this on our end?

Did you use the WiX Toolset in order to generate it as explained in the "How to create fully fledged C# custom actions" article?

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
odaniel
Posts: 10
Joined: Thu May 14, 2020 3:33 pm

Re: Using a DLL to set APPDIR

It's a standard dll written in C++ and built with Visual Studio 2019. I created 2 export functions with the standard calling convention.

Below is a minimalist version of the function that I am calling to get installation path. The return value is assigned to a property.

Code: Select all

char		g_szInstallPath[_MAX_PATH];

_declspec(dllexport) LPCSTR __stdcall GetInstallPath()
{
      // this is where the logic to determine the installation path based on the user's office location would be
      // the path would be written to g_szInstallPath

     return g_szInstallPath;
}
The returned string pointer is actually the address of a character array declared as a global within the dll since I didn't know how the installer would allocate memory to return a string. The "call by reference" terminology in the installer project UI was confusing to me so I decided to play it safe by storing the string on my end. The function is also declared in the list of exports in a library definition file (.DEF).

Again it works correctly for me when used in Custom Actions that occur later in the install process. I'm just having problems when I try to use it earlier in the process.
Catalin
Posts: 6596
Joined: Wed Jun 13, 2018 7:49 am

Re: Using a DLL to set APPDIR

Hello Daniel,

Unfortunately, I can not say for sure why this happens.

Could you please forward me a copy of your .DLL file by e-mail at support at advancedinstaller dot com so I can run some tests on my end?

Additionally, could you please give me some more details about the expected outcome? For instance, what should I expect the .DLL to do - does it simply overwrites the APPDIR property to a custom path?

Looking forward to hearing from you.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
odaniel
Posts: 10
Joined: Thu May 14, 2020 3:33 pm

Re: Using a DLL to set APPDIR

I just sent the dll. I really appreciate you taking the time to look into this.

Oliver
Catalin
Posts: 6596
Joined: Wed Jun 13, 2018 7:49 am

Re: Using a DLL to set APPDIR

Hello Oliver,

I have answered you over the email.

Looking forward to hearing from you!

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube

Return to “Building Installers”