I already suspect it is not possible and likely to be hardcoded, requiring modification of the Inno Setup source code, however Inno Setup is extremely flexible, so maybe there is a way?
Is it possible to change what is displayed in the Windows Task Manager Description field for Setup.tmp that runs with Setup.exe, from 'Setup\Uninstall' to something else?
I have already checked if this is one of the default messages that can be modified.
If not possible directly in Inno Setup, as I suspect, would modifying the resources with something like Resource Hacker or Resource Tuner make this possible? Alternatively, is there another esoteric way of doing this without modifying the Inno Setup source code?
You have to edit the "Version Info" of the Setup.e32 using a tool like Resource Hacker.
1 VERSIONINFO
FILEVERSION 51,1052,0,0
PRODUCTVERSION 0,0,0,0
FILEOS 0x4
FILETYPE 0x1
{
BLOCK "StringFileInfo"
{
BLOCK "000004B0"
{
VALUE "FileDescription", "Setup/Uninstall of My Program"
VALUE "FileVersion", "51.1052.0.0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0000 0x04B0
}
}
Related
I'm trying to solve a problem I'm having with an Azure ARM template, whereby I need to capture the output of a queried resource in my ARM template, then in that same template, feed that output into a variable / inject that output into a script on another resource that depends on it.
An example -
"outputs":{
"downloadLocation": {
"type": "string",
"value": "[reference(resourceId('randomResource', variables('ResourceName'))).downloadLocation]"
}
}
And
variables: {
"downloadLocation": "[outputs('downloadLocation')]"
}
This variable is then referenced in one of the resources that depends on the source of the queried output.
The downloadLocation can't be formatted in anyway, it contains several signatures and unpredictable strings.
FYI - the below code stops the arm template from being used, by producing the error 'The template function 'outputs' is not valid.'
I'm not locked to storing it as an output, I just need to be able to use that value in another resource - however it's achieved!
The only other route I know would work, but I don't want to explore yet, is that the output could be stored in a file somewhere, then a subsequent script picks it up and injects it into a second ARM template.
If there is a way to use this please let me know, it would help me out significantly!
Thanks
I have found the solution.
The reference function can be called when inside a resource field. So I've had to use reference function as seen above, but it can't be stored in a variable or parameter, it instead needs to be called directly in the resource that's requiring it. Which in this case was the osProfile - customData field.
I would like to read these three values from my application.exe in my Inno Setup script.
[assembly: AssemblyCompany("My Company")]
[assembly: AssemblyProduct("My Great Application")]
[assembly: AssemblyFileVersion("9.3.2")]
Does anyone know how this might be accomplished?
I know I can get the last one using GetFileVersion("path/to/greatapp.exe")
is there something similar for the first two?
Use the GetStringFileInfo() function provided by the Inno Setup Preprocessor (ISPP) as follows:
GetStringFileInfo("path/to/greatapp.exe", "CompanyName")
GetStringFileInfo("path/to/greatapp.exe", "ProductName")
GetStringFileInfo("path/to/greatapp.exe", "FileVersion")
As you have already mentioned, you can use the GetFileVersion() function instead of #3 above.
Also, have a look at the ISPPBuiltins.iss script file included with your Inno Setup installation. It contains a GetFileCompany() function to use instead of #1 above and you can implement #2 above in a similar fashion.
I dont know Inno Setup but I guess it supports custom actions like the other setup tools (Visual Studio, Wix, InstallShield or Wise).
So, you will need to create a custom action to read this information from the assembly. In your custom action, you need to add the following code to fetch the assembly attributes:
Assembly assembly = Assembly.LoadFrom (#"path\to\greatapp.exe");
object[] attributes = assembly.GetCustomAttributes(true);
if (attributes.Length > 0)
{
foreach (object o in attibutes)
{
//Do Something with the attribute
}
}
I've just created a custom dialog with a checkbox asking if the user wants to create a desktop shortcut. I used to always include a shortcut I'm not using the AskText() function as I plan on adding more pieces to this page later and want to simplify these few options to this one page.
I get an item on my desktop when I run, but it's not what I expect. The target seems to be pointing to a location on the desktop itself and not the actual executable. Also, this shortcut does not delete on uninstall (I'm assuming this needs to be handled separately anyway) and the shortcut needs admin rights to be manually deleted (which I don't want, for obvious reasons).
Below is my InstallScript code. It is in a custom action that was inserted after InstallFiles.
function MyFunction(hMSI)
STRING szProgramFolder, szItemName, szCommandLine, szWorkingDir;
STRING szShortCutKey, szProgram, szParam, szIconPath;
NUMBER nIcon, nResult;
begin
szProgramFolder = FOLDER_DESKTOP;
szItemName = "myProgram";
szProgram = INSTALLDIR + "myProgram.exe" ;
LongPathToQuote (szProgram, TRUE);
szCommandLine = szProgram;
szWorkingDir = INSTALLDIR;
szIconPath = "";
nIcon = 0;
szShortCutKey = "";
nResult = AddFolderIcon (szProgramFolder, szItemName, szCommandLine,szWorkingDir,
szIconPath, nIcon, szShortCutKey, REPLACE);
end;
I'm not quite sure where I'm going wrong here, although my knowledge of InstallShield (let alone InstallScript) is very limited.
As it turned out, this is a deferred custom action, hence the INSTALLDIR variable is not initialized (nor any other Windows Installer built-in variables). Change it to an Immediate-type custom action (and relocate it to an appropriate location in the execution sequence) and it should work.
To fix the shortcut's parameters, start by ensuring they are correct. Debug your function to verify you are actually passing what you want to. As commented, INSTALLDIR may not be available directly to an InstallScript custom action. A simple way to "debug" would be to add calls like MessageBox(szCommandLine, 0); to key points in your code. If you find you are passing something like C:\Program Files\Company\ProductmyProgram.exe, consider using the ^ operator to concatenate your paths: szProgram = INSTALLDIR ^ "myProgram.exe";.
To uninstall the shortcut, you have to understand that custom actions in MSI projects are not automatically reversed. So use a different approach. Either explicitly code up its removal during uninstall in another action, switch to pure InstallScript where logging will reverse your actions, or go with a proper MSI-based approach. For the last of those, define the shortcut in its own component, and give the component a condition that correlates to a property you set in your UI (or via AskText for now), or skip the condition and just use feature selection by putting the component in a child feature. Then Windows Installer will track and remove the shortcut for you.
Is there a way to prevent ReSharper from formatting a specific code block in a file? Something like:
void MyMethod ()
{
// ReSharper disable formatting
PRE = { my top format } /* no rules */ ;
// ReSharper enable formatting
}
Now it is possible in version 2017.3 like this:
// #formatter:off — disable formatter after this line
// #formatter:on — enable formatter after this line
At the moment this is not possible. See feature request RSRP-187963.
As a workaround, if you have a big chunk of "pre-formatted" code, you could move it to an own (partial class) file and add it to the "Generated Code" configuration list. This disables R#'s "Code Cleanup" for this file. Note that it also disables the inspections! (Unfortunately the "Generated Code Region" feature only disables the inspections, not the "Code Cleanup" for a region, as of R# version 9.2.)
How to change font in all dialog forms in a visual c++ application?
I want to set Tahoma style.
Thanks.
You can set the font for a dialog in the resource it's created from. I believe that'll change the font on all the standard controls as well. If you have custom controls, you'll have to do additional work.
Note that if you want to have the font match the default UI font for the computer, then you can use a virtual font like "MS Shell Dlg 2" which will be mapped to Tahoma on XP, and Segoe UI on Vista+.
Replacing font in each dialog of your application would be rather tedious job.
You can employ MFC to do it for you.
Check InitInstance of your app. Look at AfxEnableControlContainer();
It is being called woithout any parameter even though AfxEnableControlContainer is declared as
void AFX_CDECL AfxEnableControlContainer(COccManager* pOccManager=NULL);
COccManager is a very interesting class and is used when has occ ( OLE custom controls) support, managing OLE container and site classes. All MFC applications are created by default with occ support. If you do not see AfxEnableControlContainer in the code generated by wizard, you do not have occ support enabled.
Anyway, instead using default occ implementation, use own and change it to change the font.
Derive class from COccManager. In this sample I call it CDlgOccManager. Override virtual PreCreateDialog:
virtual const DLGTEMPLATE* PreCreateDialog(_AFX_OCC_DIALOG_INFO* pOccDialogInfo,
const DLGTEMPLATE* pOrigTemplate);
In the implementation:
const DLGTEMPLATE* CDlgOccManager::PreCreateDialog(_AFX_OCC_DIALOG_INFO* pOccDialogInfo, const DLGTEMPLATE* pOrigTemplate)
{
CDialogTemplate RevisedTemplate(pOrigTemplate);
// here replace font for the template
RevisedTemplate.SetFont(_T("Tahoma"), -16);
return COccManager::PreCreateDialog (pOccDialogInfo, (DLGTEMPLATE*)RevisedTemplate.Detach());
}
Now you are changin font for all dialogs. Remember changing AfxEnableControlContainer call:
PROCESS_LOCAL(CDlgOccManager, pManager);
BOOL CDlgFontChangeApp::InitInstance()
{
AfxEnableControlContainer(pManager.GetData());
.
.
.
}
DO not forget to
#include "DlgOccManager.h"
For new verion of the MFC include afxdisp.h for older, occimpl.h for COccManager.
I just noticed something. It is not a blunder but it needs an explanation.
I have kept this code in my repository for a very, very, very long time.
It was a time when DLLs kept all data as global, making data available to all modules that loaded this dll. In order to force data to be stored in TLS area, I used PROCESS_LOCAL macro that expands to invoking CProcessLocal class that is still alive.
You can remove this macro and replace it with:
BOOL CDlgFontChangeApp::InitInstance()
{
CDlgOccManager* pManager = new CDlgOccManager();
AfxEnableControlContainer(pManager);
.
.
.
}