How to register a .NET DLL using Inno Setup - 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.

Related

Inno Setup ParseVersion is not callable from [Code]

The macros ParseVersion and RemoveBackslash, for example, are both declared in ISPPBuiltins.iss. If I attempt to call both from within [Code]:
function InitializeSetup: Boolean;
var
Major, Minor, Rev, Build: Integer;
begin
RemoveBackslash('123\');
ParseVersion('12345', Major, Minor, Rev, Build);
end;
RemoveBackslash compiles fine, but adding ParseVersion causes a compiler error:
Unknown identifier 'ParseVersion'"
When part of another macro declaration, ParseVersion seems to compile fine, just not from [Code]. Should I be able call it like that?
As #Andrew wrote already, the ParseVersion (or actually since Inno Setup 6.1, the GetVersionComponents) is a preprocessor function. So it has to be called using preprocessor directives and its results stored into preprocessor variables.
#define Major
#define Minor
#define Rev
#define Build
#expr GetVersionComponents("C:\path\MyProg.exe", Major, Minor, Rev, Build)
If you need to use the variables in the Pascal Script Code, you again need to use preprocessor syntax. For example:
[Code]
function InitializeSetup: Boolean;
begin
MsgBox('Version is: {#Major}.{#Minor}.{#Rev}.{#Build}.', mbInformation, MB_OK);
Result := True;
end;
The above is true, if you really want to extract the version numbers on the compile-time. If you actually want to do it in the Code section, i.e. on the install-time, you have to use Pascal Script support function GetVersionComponents (yes, the same name, but a different language):
[Code]
function InitializeSetup: Boolean;
var
Major, Minor, Rev, Build: Word;
Msg: string;
begin
GetVersionComponents('C:\path\MyProg.exe', Major, Minor, Rev, Build);
Msg := Format('Version is: %d.%d.%d.%d', [Major, Minor, Rev, Build]);
MsgBox(Msg, mbInformation, MB_OK);
Result := True;
end;
The Pascal Script function GetVersionComponents is available since Inno Setup 6.1 only.
The RemoveBackslash works in both contexts, as there's both Pascal Script RemoveBackslash and Preprocessor RemoveBackslash.
In the Change Log (for 6.1.x) it mentioned:
Support function GetFileVersion and ParseVersion have been renamed to GetVersionNumbersString and GetVersionComponents respectively. The old names are still supported, but it is recommended to update your scripts to the new names and the compiler will issue a warning if you don't.
So be wary of that when you upgrade. But as you rightly say, these are Inno Setup Preprocessor (ISPP) functions. With respects to the Pascal Script section there is nothing listed in the Support Function Reference.
Someone else might be able to shed more insight about this, or offer a workaround, but you might have to request the feature in the Info Setup forum.

Inno Setup: Invalid Prototype

I am getting an "Invalid prototype for 'CheckForFile'". After hours and hours of trying to make setup download and install file (download part works, but I cannot find a way to run downloaded file), I am out of ideas. Why I am getting that error on this?
[Run]
Filename: "{tmp}\AcroRdrDC1800920044_en_US.exe"; Description: "Install Adobe Reader"; Flags: shellexec skipifsilent; BeforeInstall: CheckForFile('{tmp}\AcroRdrDC1800920044_en_US.exe');
[Code]
function CheckForFile(Param: String): Boolean;
begin
Result := FileExists(Param)
end;
While there already is some truth within the comments, I'd like to share what I've learned so far anyway, just in case anyone needs it.
My observations are
If I use the Check parameter with a function that returns a boolean, there is no Invalid Prototype error
If I use the BeforeInstall or AfterInstall parameter with a procedure there is no error either
Any other combination will cause the error
This led me to the following conclusion:
When using a procedure or function within the parameters of [Files] entry, Inno Setup creates a prototype for this function or procedure.
A procedure prototype for BeforeInstall and AfterInstall, since these do not expect a return value
A function : boolean protoype for Check, because this one expects a return value
After processing the [Files] section, the [Code] section is processed. Since a prototype for CheckForFile has already been declared as procedure CheckFile(...); the declaration function CheckFile(...) : boolean does not match the prototype and the error is shown.
Therefor changing the function to a procedure would work techically, but using Check would be the way to go in your case. In cases when we want to execute something before the installation, BeforeInstall is the way to go, but it does not allow returning values.

Semi-Transparent Wizard Form

I was working on an Inno Setup design when I faced this mighty question in front of me...How to make the Wizard form semi-transparent?
I know Delphi too so I'm thinking if there is any way we can use FMX's Fill.Color and transparency=true with Inno Setup?
I'm currently using this function for Wizard creation:
procedure CreateWizardForm;
begin
with WizardForm do begin
BorderStyle:=bsNone;
ClientWidth:=900;
ClientHeight:=540;
InnerNotebook.Hide;
OuterNotebook.Hide;
Center;
Bevel.Hide;
NextButton.Width:=0;
CancelButton.Width:=0;
end;
Form:=ImgLoad(WizardForm.Handle,ExpandConstant('{tmp}')+'\form.png',0,0,900,540,True,True);
end;
Regards
Ramiro
There is Inno Setup plug-in as for NSIS called IsWin7 or MegaFileUpload.
It works for Windows Vista and Windows 7 - both systems support Aero effects.
Keep in mind that iswin7.dll is non-official.
Sample:
[Files]
Source: ".\ISWin7.dll"; DestDir: "{tmp}"; Flags: dontcopy nocompression
[Code]
procedure iswin7_add_glass(Handle:HWND; Left, Top, Right, Bottom : Integer; GDIPLoadMode: boolean);
external 'iswin7_add_glass#files:iswin7.dll stdcall';
procedure iswin7_add_button(Handle:HWND);
external 'iswin7_add_button#files:iswin7.dll stdcall';
procedure iswin7_free;
external 'iswin7_free#files:iswin7.dll stdcall';
procedure InitializeWizard();
begin
iswin7_add_button(WizardForm.BackButton.Handle);
iswin7_add_button(WizardForm.NextButton.Handle);
iswin7_add_button(WizardForm.CancelButton.Handle);
iswin7_add_glass(WizardForm.Handle, 0, 0, 0, ScaleY(47), True);
end;
procedure DeinitializeSetup();
begin
iswin7_free;
end;
Is the feature you are trying to achieve called Aero (from Windows Vista)?
I think this is not possible to do in pure Inno Setup.
Check this NSIS plug-in: http://nsis.sourceforge.net/Aero_plug-in.
It is open source and uses some Windows API functions -- for inspiration.

Inno Setup: how to call custom functions from the InstallDelete section

I would need Inno Setup generated installer to delete certain files prior installation if the software is already installed with an older version.
I tried to do this by comparing version numbers (custom function below) but when compiling, Inno Setup generates an error:
[ISPP] Undeclared identifier: "GetInstalledVersion".
The Inno Setup script relevant extract is:
(...)
[Code]
function GetInstalledVersion(MandatoryButNotUsedParam: String): String;
var Version: String;
begin
if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ExpandConstant('AppId')+'_is1', 'DisplayVersion') then
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\'+ExpandConstant('AppId')+'_is1', 'DisplayVersion', Version);
MsgBox(ExpandConstant('Existing version:'+Version+' New version:'+ExpandConstant('AppVersion')), mbInformation, MB_OK);
Result := Version;
end
else
begin
Result := '';
end
end;
(...)
[InstallDelete]
#define InstalledAppVersion GetInstalledVersion('')
#if "1.013" > InstalledAppVersion
Type: files; Name: {userappdata}\xxx\*.hhd
#endif
Being new to Inno Setup, this is certainly a trivial question but no answer found on forums. The question is thus: how can I properly call the function GetInstalledVersion from the [InstallDelete] section?
Is there an issue because [InstallDelete] section might be called before [code] section is read?
Many thanks for any help / hint!
Do you want to check for currently installed version and if it's below 1.013,
then remove user files from {userappdata}\xxx\*.hhd ?
then what you need is parameter Check http://www.jrsoftware.org/ishelp/index.php?topic=scriptcheck
[Code]
function isOldVersionInstalled: Boolean;
begin
// Result := <True|False>;
end;
[InstallDelete]
Type: files; Name: {userappdata}\xxx\*.hhd; Check:isOldVersionInstalled;
What is wrong with your example:
You are calling a Pascal function from the pre-processor.
Those are two different things.
You can define a macro in pre-processor - that's kind of like a function,
but that's not what you want because Pre-processor only runs on compile time and so it can't be used to check on state of User's files/environment.

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