zchaibi
Posts: 3
Joined: Tue May 07, 2024 1:56 pm

Trouble Calling Windows API Functions in Advanced Installer

Hello everyone,

I'm currently facing an issue while migrating my application setup from Inno Setup to Advanced Installer. In my application, I'm utilizing the Windows API functions AddMonitor, AddPrinterDriver, and AddPrinter from the winspool.drv library directly to add a virtual printer. This setup works flawlessly with Inno Setup.

However, in the process of transitioning to Advanced Installer, I've encountered difficulties in directly calling these functions. I attempted to use the "Call Function from Standard DLL" feature, but unfortunately, it didn't yield the expected results.

Has anyone successfully integrated such Windows API calls directly within Advanced Installer? Any insights or suggestions on how to overcome this hurdle would be greatly appreciated.

Thank you in advance for your help!

Best regards,
Catalin
Posts: 6667
Joined: Wed Jun 13, 2018 7:49 am

Re: Trouble Calling Windows API Functions in Advanced Installer

Hello and welcome to our forums,

If possible, could you please let me know how you did call the functions in InnoSetup so I can see whether we have a similar support or not?

In the past, I have written the following article which explains how one can use PowerShell to call Windows API functions:

Use PowerShell to call Windows API functions

but I would like to see whether we can improve our current support to also cover your scenario (if not already supported). :)

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
zchaibi
Posts: 3
Joined: Tue May 07, 2024 1:56 pm

Re: Trouble Calling Windows API Functions in Advanced Installer

Hello Catalin,

Thank you very much for your response and your willingness to improve support in Advanced Installer.

In InnoSetup, I used standard calling via Pascal to access the necessary Windows API functions. Here are the functions I used, along with their signatures:

Pascal

Code: Select all

function SetDefaultPrinter(lpPrinterName: String): LongInt;
 external 'SetDefaultPrinterA@winspool.drv stdcall';
function AddMonitor (pName:String; Level:LongInt; var pMonitors:TMonitorInfo2): LongInt;
 external 'AddMonitorA@winspool.drv stdcall';
function AddPrinterDriver (pName:String; Level:LongInt; var pDriverInfo:TDriverInfo3):LongInt;
 external 'AddPrinterDriverA@winspool.drv stdcall';
function AddPrinter(pName:String; Level: Longint; var pPrinter2: TPrinterInfo2): LongInt;
 external 'AddPrinterA@winspool.drv stdcall';
These functions allowed me to interact with the Windows API for printer management effectively.

Thank you for considering how Advanced Installer can better support such scenarios.

Best regards,
zchaibi
Catalin
Posts: 6667
Joined: Wed Jun 13, 2018 7:49 am

Re: Trouble Calling Windows API Functions in Advanced Installer

You are always welcome, zchaibi!

Is the article I've provided useful to you?

From what I can see, achieving this using InnoSetup is quite similar to my article.

Best regards,
Catalin
Catalin Gheorghe - Advanced Installer Team
Follow us: Twitter - Facebook - YouTube
zchaibi
Posts: 3
Joined: Tue May 07, 2024 1:56 pm

Re: Trouble Calling Windows API Functions in Advanced Installer

Dear Catalin,

I appreciate your prompt response. I'm reaching out regarding the PowerShell script I've been working on to add a virtual printer driver. Despite my efforts, it seems that the script isn't functioning as expected.

Code: Select all

Add-Type @"
using System;
using System.Runtime.InteropServices;

public class Win32Helper {
    [DllImport("winspool.drv", EntryPoint="AddPrinterDriverA", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern uint AddPrinterDriver(string pName, uint Level, ref TDriverInfo3 pDriverInfo);
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TDriverInfo3 {
    public uint cVersion;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pEnvironment;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pDriverPath;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pDataFile;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pConfigFile;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pHelpFile;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pDependentFiles;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pMonitorName;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string pDefaultDataType;
}
"@

# Appel des fonctions pour installer une imprimante
$driverName = "MyDriver"

# Appel de la fonction SetDefaultPrinter pour définir l'imprimante par défaut
[System.UInt32] $result1 = 0
#[Win32Helper]::SetDefaultPrinter($printerName)

# Définition des structures pour le moniteur, le pilote et l'imprimante
$driverInfo = New-Object TDriverInfo3
$driverInfo.cVersion = 3
$driverInfo.pName = $driverName
$driverInfo.pEnvironment = "Windows x64"
$driverInfo.pDriverPath = "PSCRIPT5.DLL"
$driverInfo.pDataFile = "ADIST5.PPD"
$driverInfo.pConfigFile = "PS5UI.DLL"
$driverInfo.pHelpFile = "PSCRIPT.HLP"
$driverInfo.pDependentFiles = "PSCRIPT.NTF"
$driverInfo.pMonitorName = "MyMonitor"
$driverInfo.pDefaultDataType = "RAW"
[System.UInt32] $result3 = [Win32Helper]::AddPrinterDriver($driverName, 3, [ref] $driverInfo)

if ($result3 -eq 0 ) {
    Write-Host "L'imprimante a été installée avec succès."
} else {
    Write-Host "Erreur lors de l'installation de l'imprimante."
}
Unfortunately, I'm not receiving any error messages during script execution, which makes troubleshooting a bit challenging. After running the script, I checked the registry, but I couldn't find any indication that the driver was successfully installed. This is quite perplexing, especially considering that a similar process using Inno Setup has been successful in the past.

Do you have any insights or suggestions on how I can debug this issue further? I've double-checked to ensure that the script is being executed with administrative privileges, but I'm still unable to identify the root cause of the problem.

Thank you once again for your assistance and support.

Best regards,
zchaibi
Catalin
Posts: 6667
Joined: Wed Jun 13, 2018 7:49 am

Re: Trouble Calling Windows API Functions in Advanced Installer

Hello zchaibi,

I am sorry to hear that you have not managed to get this working. :(

Upon further investigation on this, I found that PowerShell actually has some predefined support (cmdlets) for what you need, meaning we might not need to call the Windows API functions anymore.

Here's what I was able to find so far:

Add-Printer cmdlet

Add_PrinterDriver cmdlet

The above two should be exactly what you are looking for and I have a feeling they might be using the same Windows API calls behind the scene.

Could you please have a look over those and then test them (first from a PowerShell prompt in a VM, for example and then through Advanced Installer)?

Hope this helps!

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

Return to “Common Problems”