Playing native Windows sounds in Inno Setup - inno-setup

In there any way to play Windows native sounds using Inno Setup?
For example I'm showing a custom message box, and I need to play Windows warning/info/error sound before showing that message. Any way?

Use PlaySound WinAPI function:
const
SND_ASYNC = $0001;
SND_ALIAS = $00010000;
function PlaySound(pszSound: string; hmod: THandle; fdwSound: DWORD): BOOL;
external 'PlaySoundW#Winmm.dll stdcall';
Use it like:
PlaySound('SystemQuestion', 0, SND_ALIAS or SND_ASYNC);
For list of standard sound aliases, see:
https://learn.microsoft.com/en-us/windows/win32/multimedia/using-playsound-to-play-system-sounds

Related

Setup Programs created using Inno Setup Compiler doesn't display Minimize Animation

My Problem is why Inno Setup Compiler (Unicode or ANSI) and any Setups made by it don't minimize showing a nice Minimizing Animation like in Other Windows Programs?
It displays a very basic Minimize Animation..........Why that?
I know Borland Delphi as Inno Setup Compiler's Compiler, but Borland Delphi doesn't have such a bad Minimize Animation...........It minimizes normally as Windows System Windows minimize (such as Explorer, Computer, Control Panel).................
I also noticed that the Windows Installer Creater Nullsoft Scriptable Install System - NSIS and Setups made using it are also minimizing well like I said.
How can I resolve this problem?
UPDATED QUESTION
I also added a code to play that nice Zooming Minimize / Restore Animation can be seen in Many Windows Applications on Inno Setup's WizardForm, But when I click the WizardForm's Minimize Button after adding this code to Inno Setup Compiler's Source Code, the Nice Zooming animation not plays and it never can be minimized using it, it only can be minimized using Taskbar button after adding this code. So it means this code not working or anything else wrong...........Why this is not working???
The Code I Added to unit WizardForm:
interface
uses
Windows;
type
TTrayZoom = class(TObject)
private
class function GetTrayRect: TRect;
class procedure DoZoom(const Wnd: HWND; const Src, Dest: TRect);
public
class procedure ZoomToTray(const Wnd: HWND);
class procedure ZoomFromTray(const Wnd: HWND);
end;
implementation
class procedure TTrayZoom.DoZoom(const Wnd: HWND; const Src, Dest: TRect);
begin
DrawAnimatedRects(Wnd, IDANI_CAPTION, Src, Dest);
end;
class function TTrayZoom.GetTrayRect: TRect;
var
TaskbarWnd, TrayWnd: HWND;
begin
TaskbarWnd := FindWindow('Shell_TrayWnd', nil);
TrayWnd := FindWindowEx(TaskbarWnd, 0, 'TrayNotifyWnd', nil);
GetWindowRect(TrayWnd, Result);
end;
class procedure TTrayZoom.ZoomFromTray(const Wnd: HWND);
var
WndRect: TRect;
begin
GetWindowRect(Wnd, WndRect);
DoZoom(Wnd, GetTrayRect, WndRect);
end;
class procedure TTrayZoom.ZoomToTray(const Wnd: HWND);
var
WndRect: TRect;
begin
GetWindowRect(Wnd, WndRect);
DoZoom(Wnd, WndRect, GetTrayRect);
end;
And I called TTrayZoom.ZoomToTray from if WMSysCommand..... = SCMINIMIZE and called TTrayZoom.ZoomFromTray from if WMSysCommand..... = SCRESTORE with the setting HWND parameter to WizardForm.Handle.
But those codes never works, I even don't know if they're get called or not. :(
What is the problem playing this Zooming Animation in this WizardForm?
I'd say there are two issues.
The animation is shown for windows that have a task bar button. The wizard form does not have a task bar button.
The task bar button of the installer belongs to a hidden main window.
Historically the installers had full screen background gradient blue windows. Even Inno Setup supported that.
While that background window is no longer enabled by default (the WindowVisible directive defaults to No in modern versions of Inno Setup), it still exists and owns the task bar button.
Inno Setup is built using an ancient version of Delphi that likely does not play nicely with the minimize feature.
Generally, I'd say you should file a feature request/bug report to get this fixed.

In Inno Setup, how can I get the start type of an existing service. (SERVICE_BOOT_START, SERVICE_SYSTEM_START etc.)

In Inno Setup, how can I get the start type of an existing service? (SERVICE_BOOT_START, SERVICE_SYSTEM_START etc.)
I've come across
function QueryServiceStatus(hService :HANDLE;var ServiceStatus :SERVICE_STATUS) : boolean;
external 'QueryServiceStatus#advapi32.dll stdcall';
But SERVICE_STATUS does not include start type.

How to use AObject in the AddCheckBox function when using the componentslist?

I am trying to understand the AddCheckBox function in inno pascal script. The documentation is limited:
http://www.jrsoftware.org/ishelp/index.php?topic=scriptclasses
function AddCheckBox(const ACaption, ASubItem: String; ALevel: Byte; AChecked, AEnabled, AHasInternalChildren, ACheckWhenParentChecked: Boolean; AObject: TObject): Integer;
How to use the "AObject" argument? Of course I can just use "nil" but this causes an error message about a memory once the user clicks on the added checkbox.
It may be relevant that I want to add a checkbox to the componentslist (dynamically) of the WizardForm. So it is something like:
WizardForm.ComponentsList.AddCheckbox(..please help me with the correct arguments).
The function seems useful but to use it, I need to know what arguments to use and what they mean.

How to register a .NET DLL using Inno Setup

I have written a class library using Visual Studio 2010 C# to read hardware information of a Computer (e.g. HDD/SSD). I will use this dll to create an installer using InnoSetup to read the hardware info of the target computer. Now my problems is .NET dll cannot be used directly unless it is registered already. I am trying to find a way to register the dll during InitializeSetup in InnoSetup so I can use the functions in the dll. Here is the script I wrote for installer.
function InitializeSetup(): Boolean;
var
obj: Variant;
diskPartitions: Integer;
va: String;
ErrorCode: Integer;
b: Boolean;
begin
ExtractTemporaryFile('SSHardwareChecker.dll');
RegisterServer(False, ExpandConstant('{tmp}\SSHardwareChecker.dll'), False);
obj := CreateOleObject('SSHardwareChecker.SSClass');
va := obj.GetDiskDriveInformation;
MsgBox(va, mbInformation, mb_Ok);
b:=UnregisterServer(False, ExpandConstant('{tmp}\SSHardwareChecker.dll'), False);
end;
The function RegisterServer doesn't seem to work.It throws an error which says RegSvr32 failed with exit code 0x4. I read a lot of articles in the net that says .net dll shoud be registered using regasm. I dont really know how to do this, especially in Inno Setup.
Please help guys.
Though its more than a year, I recently had the same problem and was able to rectify using the below script.
[Run]
Filename: "{dotnet20}\RegAsm.exe"; Parameters: /codebase YourDLL.dll; WorkingDir: {app}; StatusMsg: "Registering Controls..."; Flags: runminimized
If the file has be registered at initialize step, we can use one of the Inno setup's support functions.
function Exec(const Filename, Params, WorkingDir: String; const ShowCmd: Integer; const Wait: TExecWait; var ResultCode: Integer): Boolean;
More Info can be found in:
Inno Setup Help
To do this, you MUST..
1) make sure that .net 4.0 is installed (not by default on most machines yet)
2) extract and register the DLL (you need to call regasm.exe on the extracted DLL)
This is a lot to do just to "GetDiskDriveInformation" as the very first step of the install.
It is far better to get the information natively in Inno or call a native DLL that doesn't have the prerequisites.

Uninstall fails because program is running. How do I make Inno Setup check for running process prior to attempting delete?

Inno Setup fails to remove components during uninstall cause my program is still running and the executable cannot be deleted. How do I have it check to see if it is running before allowing uninstall to proceed?
Check these
Inno Setup: Detect instances running in any user session with AppMutex
Inno Setup: Is application running?
Inno Setup: Detect if an application is running
There are several ways. If your program defines a mutex use
[Setup]
AppMutex=MyMutexName
or for a specified mutex in the Code section
function CheckForMutexes (Mutexes: String): Boolean;
You could also use
function FindWindowByClassName (const ClassName: String): Longint;
to get the window handle by class name and send it messages.
Or get it by the name
function FindWindowByWindowName (const WindowName: String): Longint;
Or you use one of several DLL files for this specific use case
PSVince
FindProcDLL
Or do it yourself after reading
How To Terminate an Application "Cleanly" in Win32
How To Enumerate Applications Using Win32 APIs (this one links to the german version as for some reason I can't find the english version of KB175030
or try the google translated version of the KB175030-DE
KB175030 DE -> EN
We used an other way than described above. Because this is an uninstallation we can kill the application and unistall it.
The simpliest way, when u can't use AppMutex: (related to Really killing a process in Windows)
[UninstallRun]
Filename: "{cmd}"; Parameters: "/C ""taskkill /im <precessname>.exe /f /t"
Hope somebody will help this. I searched a long time for this.
Try this solution! I had issues with other solutions closing the app, but Inno Setup still thought the installed files were locked.
Remember to define your constants:
#define MyAppName "AppName"
#define MyAppExeName "AppName.exe"
[Code]
function InitializeUninstall(): Boolean;
var ErrorCode: Integer;
begin
ShellExec('open','taskkill.exe','/f /im {#MyAppExeName}','',SW_HIDE,ewNoWait,ErrorCode);
ShellExec('open','tskill.exe',' {#MyAppName}','',SW_HIDE,ewNoWait,ErrorCode);
result := True;
end;
Major props to the original source of this solution.
Use the AppMutex directive to prevent the uninstaller from proceeding, when an application is running.
[Setup]
AppMutex=MyProgMutex
The application has to create the mutex specified by the directive. See the linked AppMutex directive documentation for examples.
If you want to have the uninstaller kill the application, when it is still running, use this code instead:
function InitializeUninstall(): Boolean;
var
ErrorCode: Integer;
begin
if CheckForMutexes('MyProgMutex') and
(MsgBox('Application is running, do you want to close it?',
mbConfirmation, MB_OKCANCEL) = IDOK) then
begin
Exec('taskkill.exe', '/f /im MyProg.exe', '', SW_HIDE,
ewWaitUntilTerminated, ErrorCode);
end;
Result := True;
end;
As with the AppMutex directive above, the application has to create the mutex specified in the CheckForMutexes call.
Note that for installer, you do not have to code this. The installer has restart manager built-in.
See Kill process before (re)install using "taskkill /f /im" in Inno Setup.
perhaps add this property
CloseApplications=yes
it will look at all the [Files] and [InstallDelete] elements and work using windows restart manager
https://jrsoftware.org/ishelp/index.php?topic=setup_closeapplications

Resources