I'm fighting with Qt Installer Framework for creating a shortcut for my application into start menu in Windows Platform.
I used the same script as into startmenu example, but it throws an error during the creation of the shortcut. I don't understand the reason it looks there is a problem with path in my code:
Component.prototype.createOperations = function()
{
// call default implementation to actually install README.txt!
component.createOperations();
if (systemInfo.productType === "windows") {
component.addOperation("CreateShortcut", "#TargetDir#/EurocontrolGui.exe", "#StartMenuDir#/EurocontrolGui.lnk",
"workingDirectory=#TargetDir#", "iconPath=#TargetDir#/resources/eurocontrol.ico", "description=Eurocontrol Developer Tool");
}
}
Below there is my config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Installer>
<Name>Eurocontrol Developer Tool</Name>
<Version>0.11.0</Version>
<Title>Eurocontrol Developer Tool </Title>
<Publisher>Honeywell Inc.</Publisher>
<StartMenuDir>Eurocontrol Developer Tool</StartMenuDir>
<TargetDir>#ApplicationsDirX86#/Eurocontrol Developer Tool</TargetDir>
<InstallActionColumnVisible>true</InstallActionColumnVisible>
</Installer>
I run also the Installer changing from #TargetDir#/EurocontrolGui.exe, to #TargetDir#\EurocontrolGui.exe, (the same for StartMenuDir). In this case no error was thrown and the shortcut was created although the reference was invalid.
In this case when I run Installer.exe -v from command line, I'm able to see that the path for my application is changed from
C:\Program Files(x86)\Eurocontrol Developer Tool/EurocontrolGui.exe
to
C:\Program Files(x86)\Eurocontrol Developer ToolEurocontrolGui.exe
It looks that the path are malformed during the add Operation.
Any idea how to solve it?
I'd be surprised if QtInstaller gave trouble over forward slashes, but if you want to use backslashes, I believe you have to escape them first, so instead of #TargetDir#\EurocontrolGui.exe, it should be #TargetDir#\\EurocontrolGui.exe
Below is what I'm using, which works fine. Note that I actually forgot to replace one of the '/' with '\\', but it still works.
Component.prototype.createOperations = function()
{
component.createOperations();
if (systemInfo.productType === "windows") {
component.addOperation("CreateShortcut", "#TargetDir#\\app.exe", "#StartMenuDir#/app.lnk","iconPath=#TargetDir#\\icon.ico");
}
}
Related
How do I register a custom protocol with Windows so that when clicking a link in an email or on a web page my application is opened and the parameters from the URL are passed to it?
Go to Start then in Find type regedit -> it should open Registry editor
Click Right Mouse on HKEY_CLASSES_ROOT then New -> Key
In the Key give the lowercase name by which you want urls to be called (in my case it will be testus://sdfsdfsdf) then Click Right Mouse on testus -> then New -> String Value and add URL Protocol without value.
Then add more entries like you did with protocol ( Right Mouse New -> Key ) and create hierarchy like testus -> shell -> open -> command and inside command change (Default) to the path where .exe you want to launch is, if you want to pass parameters to your exe then wrap path to exe in "" and add "%1" to look like: "c:\testing\test.exe" "%1"
To test if it works go to Internet Explorer (not Chrome or Firefox) and enter testus:have_you_seen_this_man this should fire your .exe (give you some prompts that you want to do this - say Yes) and pass into args testus://have_you_seen_this_man.
Here's sample console app to test:
using System;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
if (args!= null && args.Length > 0)
Console.WriteLine(args[0]);
Console.ReadKey();
}
}
}
Hope this saves you some time.
The MSDN link is nice, but the security information there isn't complete. The handler registration should contain "%1", not %1. This is a security measure, because some URL sources incorrectly decode %20 before invoking your custom protocol handler.
PS. You'll get the entire URL, not just the URL parameters. But the URL might be subject to some mistreatment, besides the already mentioned %20->space conversion. It helps to be conservative in your URL syntax design. Don't throw in random // or you'll get into the mess that file:// is.
If anyone wants a .reg file for creating the association, see below:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\duck]
"URL Protocol"=""
[HKEY_CLASSES_ROOT\duck\shell]
[HKEY_CLASSES_ROOT\duck\shell\open]
[HKEY_CLASSES_ROOT\duck\shell\open\command]
#="\"C:\\Users\\duck\\source\\repos\\ConsoleApp1\\ConsoleApp1\\bin\\Debug\\net6.0\\ConsoleApp1.exe\" \"%1\""
Pasted that into notepad, the file -> save as -> duck.reg, and then run it. After running it, when you type duck://arg-here into chrome, ConsoleApp1.exe will run with "arg-here" as an argument. Double slashes are required for the path to the exe and double quotes must be escaped.
Tested and working on Windows 11 with Edge (the chrome version) and Chrome
There is an npm module for this purpose.
link :https://www.npmjs.com/package/protocol-registry
So to do this in nodejs you just need to run the code below:
First Install it
npm i protocol-registry
Then use the code below to register you entry file.
const path = require('path');
const ProtocolRegistry = require('protocol-registry');
console.log('Registering...');
// Registers the Protocol
ProtocolRegistry.register({
protocol: 'testproto', // sets protocol for your command , testproto://**
command: `node ${path.join(__dirname, './index.js')} $_URL_`, // $_URL_ will the replaces by the url used to initiate it
override: true, // Use this with caution as it will destroy all previous Registrations on this protocol
terminal: true, // Use this to run your command inside a terminal
script: false
}).then(async () => {
console.log('Successfully registered');
});
Then suppose someone opens testproto://test
then a new terminal will be launched executing :
node yourapp/index.js testproto://test
It also supports all other operating system.
I'm currently using the Qt-Installer-Framework to create a setup for my application. Everything works fine for now except one thing:
If I install it to any location but C:\Program Files\MyApp, the installer won't create the registry entry for Programs and Features!
Is there a way to tell the installer to always do this?
Edit:
After trying out vairous different combinations, I do know now where the problem comes from:
If I try to install as current user only (set the AllUsers variable to false), it will always work and create an entry in HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{GUID}.
If I install for all users, however, it will try to create a key in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{GUID}. This will only work, if the installer has to elevate it's operations during installation (because I chose a directory I need admin rights for).
So, the error is: The installer won't elevate itself to create the "global" registry entry and thus fails to create it. Any ideas on how to fix it?
Here the link which has answer to this question.
Add the following line to your component's package xml file:
#<RequiresAdminRights>true</RequiresAdminRights>#
And use this line in your script file:
#component.addElevatedOperation("Execute", "someCommand");#
instead of
#component.addOperation("Execute", "someCommand");#
There is boolean installer.gainAdminRights() to gain elevated privileges during runtime but you will have to add it to an installer script (in packages meta directory) something alike
function Component()
{
if (!installer.isInstaller())
{
if (allUsers && installer.gainAdminRights())
{
//Set registry global
} else {
//Set registry local
}
}
}
this is another error am getting
FAILURE: Build failed with an exception.
What went wrong:
ANDROID_HOME not specified. Either set it as a gradle property, a system environment variable or directly in your build.gradle by setting the extension jfxmobile.android.androidSdk.
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
i think, you have to add your android path on your build.gradle . Here is my setting for the android part:
jfxmobile {
android {
// signingConfig {
// storeFile file("")
// storePassword ''
// keyAlias ''
// keyPassword ''
// }
applicationPackage = 'my.package.app.name'
manifest = 'src/android/AndroidManifest.xml'
resDirectory = 'src/android/res'
androidSdk ="$System.env.HOME/android-sdks" // this is bassicly path to your android sdk
}
}
Try it.
Regards,
Ivan
Since you haven't defined the OS you are using, I'll go ahead and include both.
Ubuntu (or any other Linux distro I think):
Add the following to your ~/.bashrc file.
First
nano ~/.bashrc
Then add the following in the last line
export ANDROID_HOME= "Enter you sdk path"
This path will end with a /Android/sdk/
For eg. mine is /home/Android/sdk/
Log out and log in again and presto, magic!
If bashrc does not seem to work. Use profile instead ie ~/.profile
Remember to log out to allow changes to occur on startup.
Windows:
We can't define names to exported paths in Windows(as far as I know) so we need to include it in the build.gradle
jfxmobile {
android {
compileSdkVersion = '15'
buildToolsVersion = '22.0.1'
androidSdk = 'C:/Users/your username/AppData/Local/Android/sdk'
}
ios {
infoPList = file('src/ios/Default-Info.plist')
}
}
And hey, there's the magic again!
If you installed Android somewhere else, point it to the correct direction.
Use the gluon plugin for Netbeans. Its the best way I found for working with javafxports. It takes all headaches from customizing basic things out of the way.
Why set it globally in Ubuntu and not in the build.gradle file?
Declaring it globally is an approach which means you don't have to repeat the same process again in a new project.
$ wget --quiet http://download.qt-project.org/official_releases/qt/5.2/5.2.1/qt-opensource-windows-x86-msvc2012_64_opengl-5.2.1.exe
$
As seen above, I first downloaded the Qt package for Visual Studio in a Cygwin Bash shell.
A sidenote: The Qt library packaged within Cygwin is not useful for me because I need to use the Visual Studio C++ compiler.
First I set the correct permissions on the file
$ chmod 755 qt-opensource-windows-x86-msvc2012_64_opengl-5.2.1.exe
If I start it like this
$ ./qt-opensource-windows-x86-msvc2012_64_opengl-5.2.1.exe
a graphical window (GUI) is shown but that is not what I want as I would later like to have the installation procedure written into a Bash script that I could run in Cygwin.
If I add the option --help, like this
$ ./qt-opensource-windows-x86-msvc2012_64_opengl-5.2.1.exe --help
a new terminal window is opened with the following text
Usage: SDKMaintenanceTool [OPTIONS]
User:
--help Show commandline usage
--version Show current version
--checkupdates Check for updates and return an XML file describing
the available updates
--updater Start in updater mode.
--manage-packages Start in packagemanager mode.
--proxy Set system proxy on Win and Mac.
This option has no effect on Linux.
--verbose Show debug output on the console
--create-offline-repository Offline installer only: Create a local repository inside the
installation directory based on the offline
installer's content.
Developer:
--runoperation [OPERATION] [arguments...] Perform an operation with a list of arguments
--undooperation [OPERATION] [arguments...] Undo an operation with a list of arguments
--script [scriptName] Execute a script
--no-force-installations Enable deselection of forced components
--addRepository [URI] Add a local or remote repo to the list of user defined repos.
--addTempRepository [URI] Add a local or remote repo to the list of temporary available
repos.
--setTempRepository [URI] Set a local or remote repo as tmp repo, it is the only one
used during fetch.
Note: URI must be prefixed with the protocol, i.e. file:///
http:// or ftp://. It can consist of multiple
addresses separated by comma only.
--show-virtual-components Show virtual components in package manager and updater
--binarydatafile [binary_data_file] Use the binary data of another installer or maintenance tool.
--update-installerbase [new_installerbase] Patch a full installer with a new installer base
--dump-binary-data -i [PATH] -o [PATH] Dumps the binary content into specified output path (offline
installer only).
Input path pointing to binary data file, if omitted
the current application is used as input.
I don't know how to continue from here. Do you know how I could install the Qt 5.2.1 library (for Visual Studio) from the Bash shell in Cygwin?
Update: The advantage of writing the build script for a Cygwin environment is that commands like git, wget, and scp are available. This Stackoverflow answer describes how to invoke the MSVC compiler from a Cygwin bash script. Note, that the Qt application I'm building is not going to have any dependency on Cygwin.
I didn't test with Cygwin but I successfully installed Qt5.5 using a script. To do so, you must use the --script line of the normal installer.
.\qt-opensource-windows-x86-msvc2013_64-5.5.1.exe --script .\qt-installer-noninteractive.qs
Here's an example of qt-installer-noninteractive.qs file I used in the command above
function Controller() {
installer.autoRejectMessageBoxes();
installer.installationFinished.connect(function() {
gui.clickButton(buttons.NextButton);
})
}
Controller.prototype.WelcomePageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.CredentialsPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.IntroductionPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.TargetDirectoryPageCallback = function() {
gui.currentPageWidget().TargetDirectoryLineEdit.setText("C:/Qt/Qt5.5.1");
gui.clickButton(buttons.NextButton);
}
Controller.prototype.ComponentSelectionPageCallback = function() {
var widget = gui.currentPageWidget();
widget.deselectAll();
widget.selectComponent("qt.55.win64_msvc2013_64");
// widget.selectComponent("qt.55.qt3d");
// widget.selectComponent("qt.55.qtcanvas3d");
// widget.selectComponent("qt.55.qtquick1");
// widget.selectComponent("qt.55.qtscript");
// widget.selectComponent("qt.55.qtwebengine");
// widget.selectComponent("qt.55.qtquickcontrols");
// widget.selectComponent("qt.55.qtlocation");
gui.clickButton(buttons.NextButton);
}
Controller.prototype.LicenseAgreementPageCallback = function() {
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
gui.clickButton(buttons.NextButton);
}
Controller.prototype.StartMenuDirectoryPageCallback = function() {
gui.clickButton(buttons.NextButton);
}
Controller.prototype.ReadyForInstallationPageCallback = function()
{
gui.clickButton(buttons.NextButton);
}
Controller.prototype.FinishedPageCallback = function() {
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
checkBoxForm.launchQtCreatorCheckBox.checked = false;
}
gui.clickButton(buttons.FinishButton);
}
The tricky part was to found the id of the components! I was able to found the right id qt.55.win64_msvc2013_64 by adding the flag --verbose and installing it normally with the UI and stopping at the last page; all the ids that you selected for installation are there.
There is slightly more information in this answer if you need more details.
EDIT (29-11-2017): For installer 3.0.2-online, the "Next" button in the "Welcome" page is disabled for 1 second so you must add a delay
gui.clickButton(buttons.NextButton, 3000);
EDIT (10-11-2019): See Joshua Wade's answer for more traps and pitfalls, like the "User Data Collection" form and "Archive" and "Latest releases" checkboxes.
If you run IIS Express from the command line, anything you write Console.Out in your web app is displayed in the command line output. This is very handy for trouble shooting LINQ to SQL translation issues if you set DataContext.Log = Console.Out. However, if you check "Use IIS Express" in the web project properties in VS 2010 SP1 you never see the command line.
Can you redirect IIS Express Console.Out to a log file or something?
I found a way to write directly to the Debug Console window via damieng's blog:
class DebugTextWriter : System.IO.TextWriter {
public override void Write(char[] buffer, int index, int count) {
System.Diagnostics.Debug.Write(new String(buffer, index, count));
}
public override void Write(string value) {
System.Diagnostics.Debug.Write(value);
}
public override Encoding Encoding {
get { return System.Text.Encoding.Default; }
}
}
You can attach it to a DataContext like you would with Console.Out:
#if DEBUG
db.Log = new DebugTextWriter();
#endif
http://damieng.com/blog/2008/07/30/linq-to-sql-log-to-debug-window-file-memory-or-multiple-writers
You can see console output, if you setup 'image file execution option' for iisexpress.exe. Only issue is, you will see a popup console window when a new iisexpress.exe is started. You can setup this only when you want to see console traces.
Do following to setup image file execution option:
install windbg from http://www.microsoft.com/whdc/devtools/debugging/installx86.mspx
Setup following registry key (This link may help you http://msdn.microsoft.com/en-us/library/a329t4ed(VS.71).aspx)
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\iisexpress.exe]
"Debugger"="c:\\windbg -g -G"
You can disable image file execution option by renaming or deleting above registry key.