cpack: how to associate program with file extension during install? - nsis

I'm creating a windows installer with CPack and NSIS. During the install process the user should be asked if he wants to associate my program with a file extension. At least if you do "open with..." on a file with the extension windows should be told that you can open it with my program. Does anybody know how to do this?

Go to your nsis installation folder on you system and have a look at makensis.nsi from the examples directory. It associates .nsi to makensisw.exe.
Good luck ;)

To create file associations using NSIS I would recommend using NSIS plugins mentioned by Andrei T: File Association and FileAssoc. To integrate them into CPack you need to include the script, call macro during install step, call other macro during uninstall step.
For example this is how I use "File Association" plugin:
# Including
set(CPACK_NSIS_EXTRA_PREINSTALL_COMMANDS
"!include \\\"${path_to_plugins}\\\\fileassoc.nsh\\\"")
# Create association
set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS
"\\\${RegisterExtension} '$INSTDIR\\\\myprogram.exe' '.myext' 'my_program_key'")
# my_program_key can be any string that gives some hint what this file type is about. And should not contain strings
# Remove association
set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS
"\\\${UnRegisterExtension} '.myext' 'my_program_key'")
In this implementation it is not an optional step.
Please note the double escape. It is required because CPack creates intermediate file with those strings and if you escape only once there will be a syntax error.
Also note that all CMake paths should use back slashes. I convert them with:
get_filename_component(path_to_plugins"${path_to_plugins}" ABSOLUTE)
file(TO_NATIVE_PATH "${path_to_plugins}" path_to_plugins)
string(REPLACE "\\" "\\\\" path_to_plugins"${path_to_plugins}")

Related

Internal Compile Error in NSIS

I am creating a NSIS installer which installs multiple .exe's as well. Now these other .exe's makes the installer bigger than 2GB which is the set limit. I used WinImage PlugIn which is supposed to remove the limit. I replaced the files in my NSIS folder with these of the PlugIn's but i still receive the same error. Any help will be greatly appreciated.
If you are still hitting the compiler limitation then something in your install script is still including large file(s) directly into your .exe.
To use the WinImage plug-in you first must compile a installer that just builds the .wim file locally on your machine. Then you must remove the File/File /r commands from your installer and replace them with calls to the WinImage plug-in.

CMake: How to execute a command before make install?

This is the way I install the config files:
file(GLOB ConfigFiles ${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xml
${CMAKE_CURRENT_SOURCE_DIR}/configs/*.xsd
${CMAKE_CURRENT_SOURCE_DIR}/configs/*.conf)
install(FILES ${ConfigFiles} DESTINATION ${INSTDIR})
But I need to convert one of the xml files before installing it. There is an executable that can do this job for me:
./Convertor a.xml a-converted.xml
How can I automatically convert the xml file before installing it? It should be a custom command or target that installing depends on it, I just don't know how to make the install command depend on it though. Any advice would be appreciated!
Take a look at the SCRIPT version of install:
The SCRIPT and CODE signature:
install([[SCRIPT <file>] [CODE <code>]] [...])
The SCRIPT form will invoke the given CMake script files during
installation. If the script file name is a relative path it will be
interpreted with respect to the current source directory. The CODE
form will invoke the given CMake code during installation. Code is
specified as a single argument inside a double-quoted string.
For example:
install(CODE "execute_process(\"./Convertor a.xml a-converted.xml\")")
install(FILES a-converted.xml DESTINATION ${INSTDIR})
Be sure to checkout the entry for execute_process in the manual. Also be aware that macro expansion inside the CODE parameter can be a bit tricky to get right. Check the generated cmake_install.cmake in your build directory where the generated code will be placed.
I think that your specific case would work better if you were to use a custom command and target like so:
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/a-converted.xml
COMMAND ./Convertor a.xml a-converted.xml
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/Convertor
)
add_custom_target(run ALL
DEPENDS ${CMAKE_BINARY_DIR}/a-converted.xml
COMMENT "Generating a-converted.xml" VERBATIM
)
install(
FILES ${CMAKE_BINARY_DIR}/a-converted.xml
DESTINATION ${INSTDIR}
)
Note: I don't have all the details, so the directories are probably
not exactly what you'd want in your environment, although it's
a good idea to generate files in the ${CMAKE_BINARY_DIR} area.
That way you can be sure that the file a-converted.xml is built at the time you want to install it. Especially, these two rules make sure that if you make changes to the file, it gets recompiled.

multiple binaries with same name in ubuntu/linux

I have recently installed a webframework play (http://www.playframework.com/) and want to have the play executable in the system path ie $PATH. But ubuntu already defines a command called play. How do I overwrite the system defined command with my framework binary path so that command play on commandline calls my framework rather than the old application.
Installation: I downloaded zipped file of the framework and upzipped in one of my personal folder which contains the docs and the executable.
Never alter the contents of installed packages. Such changes can provoke hard to find problems in the system and anyway, they will most likely be overwritten again in subsequent updates. There are other alternatives:
obviously you can chose another name for your executable
place the executable in another part of your $PATH if its a "personal installation", typically ~/bin is used for such approach. Remember that the order of entries in the $PATH variable is important, first come first serve.
use the traditional /usr/local/bin location for locally added "wild" installations, this way there is some form of clean separation between clean packages and wild installed files inside the system
store your software in some other location and prepend that to your personal or system wide $PATH variable
store your executable under another name and create an alias (see man alias for an explanation) for it which allows to call it by some name that "hides" the original command this way. For this the executable can be addressed with an absolute path, so it dies not have to be found inside the $PATH variable.
In my personal opinion options 2. and 5. and the best if it comes to "personal installations".
If you are sure you'll never use the original play command, you could just remove the binary. But in general, this isn't a good idea, since some system component you don't think of might need it, and the next update will probably restore it.
The best thing to do is to prepend the directory of your play command to the PATH, for example, using PATH=/opt/framework/bin:$PATH in your .profile (assuming your play command installs to /opt/framework/bin/play), or the script that starts your web server, or wherever you need your play command.
Remember that does not make your play command global. A common mistake is to add the path in their .profile file, then call the program from crontab - crontab scripts will not execute .profile or .bashrc.

How to install packages in Tcl?

I am trying to install critlib on my machine (http://equi4.com/critlib/), so that I can create zip files dynamically in Tcl.
The issue is that I have no idea how to install Tcl packages. Is there a certain place you put the folders? Is there a command like yum I can use?
I've skimmed the various Tcl beginners guides and read the sections about packages, but every source always seems to be assuming knowledge I lack.
Yes, there are some directories. To list them, execute tclsh and enter
join $auto_path \n
In each of that directory and its subdir (but not the sub-sub-dir) tcl looks for a file called pkgIndex.tcl.
So if you got an archive, extract it, look where the pkgIndex.tcl is, and copy the directory where this file is in to one of the paths $auto_path. The problem is only to select the appropiate path from the output of step 1.
If you are not sure what the appropiate directory is, I suggest editing the output from the first step into your question.
If you are using vscode and made virtual environment then you can do it as follows
"pipenv install tcl"

Extended NSIS plugins directory

I am building a plugin for NSIS with VS 2010 and I would love to set up the project so that a test setup is automatically built from a simple NSI file.
All seems fine except I can't figure out how to make NSIS look for my plugin in my project's output folder instead of C:\Program Files (x86)\NSIS\Plugins\*.dll only.
Are there any commands I can put in my NSI script to make NSIS look for my freshly built plugin outside of "standard plugins folder"? It seems rather odd to have to copy my DLL each time I wanted to test it.
Any help is appreciated.
You can use !addplugindir directive, see nsis compile-time commands.
Use !addplugindir directive with defined symbol (/D on command line).
Symbol is "the path to your location of .dll file"
For VS 2010 is the best option to use Visual & Installer - free VS addin for developing NSIS installers directly in Visual Studio.
Set your symbol in Project properties:
Download here: www.unsigned-softworks.sk/visual-installer/
As others have mentioned, the !addplugindir directive in your NSI script file will do the trick, and you can define a variable to pass to that directive on the command line using /D.
As for the code to add to your NSI file, you need something like this:
!ifdef EXTRANSISPLUGINSFOLDER
!addplugindir "${EXTRANSISPLUGINSFOLDER}"
!endif
Then on the command line, you can call your NSI script like this:
makensis.exe /DEXTRANSISPLUGINSFOLDER=C:\somefolder\moreplugins\ YourInstallerScript.nsi
When defining the extra folder, you might find that having any spaces in the folder path causes problems, and using quotes around the path doesn't help. To work around this, try using the dir /x command in the Windows terminal to list the 8.3 DOS names for the folders with spaces in their name. This will help you build up a folder path that doesn't contain spaces. (eg C:\Program Files\ often becomes C:\PROGRA~1 when listed with dir /x from the root of C:)
May have missed the point here but could you not have used an XCOPY post build event to copy the output to the NSIS plugins directory?

Resources