Can't add DialogAPI to outlook addin manifest - outlook-addin

I wan't to use displayDialogAsync in my outlook addin, but when i add DialogAPI to manifest:
<Requirements>
<Sets DefaultMinVersion="1.1">
<Set Name="Mailbox" MinVersion="1.4"/>
<Set Name="DialogAPI"/>
</Sets>
</Requirements>
I get following error: This app can't be installed. The Requirements element can only include one Set element. The name of the Set element must be 'Mailbox'..
What am i doing wrong?

The displayDialogAsync API is in both Mailbox 1.4 and DialogApi, so you don't need anything more that Mailbox 1.4. For more information, see displayDialogAsync. Scroll down to Remarks | Requirement sets.

Related

WiX File Search Conditional

I have a WiX installer project that I'm creating where I'd like the installer to check to see if another application is already installed on the user's machine. If it is, then I'd like to set the install level of one of the features to "1", otherwise it should remain hidden (i.e. install level = 0). To find out where the application is installed, I first do a registry search:
<Property Id="MYAPPINSTALLFOLDER">
<RegistrySearch Id='InstallPathRegistry'
Type='raw'
Root='HKLM'
Key='SOFTWARE\SomeLongAppPath' Name='FileName'
Win64='yes'/>
</Property>
You'll notice that the registry value that I end up getting is actually the directory of the installed application including the actual program name with extension (let's say myapp.exe). So, once I get the full path of the installed application, I check to see if the file exists:
<Property Id="MYAPPINSTALLED">
<DirectorySearch Id="CheckFileDir" Path="[MYAPPINSTALLFOLDER]" AssignToProperty="yes">
<FileSearch Id="CheckFile" Name="myapp.exe" />
</DirectorySearch>
</Property>
Now, what I would expect to see is that if the file actually exists in that location, then the Property called "MYAPPINSTALLED" would be set to 1, otherwise it would be 0. Then, when I setup my features I use something like this:
<Feature Id="ThirdPartyPlugins" Title="Third Party Plugins" Level="0">
<Condition Level="1">MYAPPINSTALLED</Condition>
<ComponentGroupRef Id="MyAppPlugin" />
</Feature>
However, when I run my installer the third party plugin feature is always hidden. I've enabled msi datalogging by setting the property like this:
<Property Id="MsiLogging" Value="voicewarmupx"/>
And when I check the log file I can definitely see that the MYAPPINSTALLFOLDER property gets changed to the correct file path when it does the registry search. However, if I search the log for the property MYAPPINSTALLED, then I can see the following:
AppSearch: Property: MYAPPINSTALLED, Signature: CheckFileDir
Action ended 15:55:06: AppSearch. Return value 1.
So, it looks like it worked, however it doesn't seem to ever set the Property to equal the search value. Am I doing something wrong? Can someone explain why my feature install level never gets set to 1 even though the application file exists?
Edit
Ok, after more debugging... I think the issue is that the directory search is trying to use a path that includes the file name and extension (i.e. C:/Program Files/MyApp/myapp.exe") instead of just the directory where the file comes from. This is because the registry search has the full path including the file name stored (but not just the install directory). If I do a directory search just using the correct absolute directory (not using the registry search) then the process works. So, my follow up question is... my Property MYAPPINSTALLFOLDER contains the full path with file name and extension. Is there a way to strip the file name and extension from this property so that I just have the proper directory name to search for?
You're checking to see if another application is installed but that's rather a long way around. Also, the file search returns a path, not zero or 1, but either way a full verbose log should tell you if the properties are being set. It might help if you could post the entire log somewhere rather than the parts you think are the only relevant ones. e.g. There's probably an AppSearch in the execute sequence for silent installs.
It's requently easier to do a single search for other applications that were installed with MSI packages in these ways:
If you know the other product's UpgradeCode (and version ranges if applicable) then add Upgrade/UpgradeVersion elements with onlydetect set to yes, and that search will set a property if the product is detected.
If you know (or can find out) the Component id of any of the relevant components from that other product, then you can use them in a WiX ComponentSearch. If you get the target property set then that component is installed. This post contains a couple of ways to find out component guids:
How to find out which application requires a certain assembly from GAC?
It's also puzzling that the AppSearch log extract you posted only refers to one property. The Directory/FileSearch is also an AppSearch, so if the MSI actually contains two searches in AppSearch there should be references to all the properties being set. Again, that's a reason to post the entire log and look in the MSI file for those searches. The RegLocator search is documnented to occur before the DRLocator, so why is there no MYAPPINSTALLFOLDER property in the AppSearch log entry? You're not on a 32-bit system are you? (noticing the win64 search).
Per the WiX documentation:
Use the AssignToProperty attribute to search for a file but set the outer property to the directory containing the file. When this attribute is set to yes, you may only nest a FileSearch element with a unique Id or define no child element [of the DirectorySearch].
I added the text in the brackets to make it more clear.
So, after reading this sentence a few times and cross referencing your WiX XML, I think I see what the problem is with your current WiX XML. You perform a separate registry search from the directory search. Instead, you should nest these. There are two ways to perform the search, depending on what you want to do. One way is to simply retrieve the registry value from the registry, and if the value exists, then you make the assumption that the feature's required application is installed, at which point you appropriately set a property that would enable hiding/showing the feature within your installer's feature selection tree. The other way is to actually find the file you're interested in, using the results of the registry search as the basis for the file search.
Below is the XML for just a registry search, which doesn't check that the file actually exists on disk. You're making the assumption that if this registry value exists, the file is installed and available.
<Property Id="MYAPPINSTALLFOLDER">
<RegistrySearch Id='InstallPathRegistry'
Type='raw'
Root='HKLM'
Key='SOFTWARE\SomeLongAppPath' Name='FileName'
Win64='yes'/>
</Property>
<Property Id="SHOW_APP_FEATURE" Value="hidden" />
<SetProperty Id="SHOW_APP_FEATURE" Value="collapse" Sequence="both" After="CostFinalize">
<!-- If MYAPPINSTALLFOLDER is defined and contains any non-empty value, this
evaluates to TRUE; otherwise, it evaluates to FALSE.
-->
MYAPPINSTALLFOLDER
</SetProperty>
<!-- You could also be more explicit:
<SetProperty Id="SHOW_APP_FEATURE" Value="collapse" Sequence="both" After="CostFinalize">
<![CDATA[MYAPPINSTALLFOLDER <> ""]]>
</SetProperty>
-->
<Feature Id="MyAwesomeFeature" Title="My Awesome App Feature"
Display="[SHOW_APP_FEATURE]">
... <!-- Component/ComponentRefs go here -->
</Feature>
If you want to ensure that, even if the registry value exists in the registry, that the file it points to is 1) actually a file path; and 2) that the file actually exists on disk, then you need to perform a nested file search within a directory search, which itself is nested within a registry search. You would again need to use a SetProperty custom action to set a property that would enable the hiding/showing of the feature within your installer's feature selection tree. Here's the XML for this search:
<!-- Performing a FileSearch nested within a DirectorySearch,
which is itself nested within a RegistrySearch
This search twill ensure that the file exists on disk, and
if so, assign the full filename and path to the
MYAPPINSTALLFOLDER property.
-->
<Property Id="MYAPPINSTALLFOLDER">
<RegistrySearch Id='InstallPathRegistry'
Type='raw'
Root='HKLM'
Key='SOFTWARE\SomeLongAppPath' Name='FileName'
Win64='yes'>
<DirectorySearch Id='InstallPathDirectory' AssignToProperty='yes'>
<FileSearch Id='InstallPathFile' Name='myapp.exe' />
</DirectorySearch>
</RegistrySearch>
</Property>
<Property Id="SHOW_APP_FEATURE" Value="hidden" />
<SetProperty Id="SHOW_APP_FEATURE" Value="collapse" Sequence="both" After="CostFinalize">
<!-- If MYAPPINSTALLFOLDER is defined and contains any non-empty value, this
evaluates to TRUE; otherwise, it evaluates to FALSE.
-->
MYAPPINSTALLFOLDER
</SetProperty>
<Feature Id="MyAwesomeFeature" Title="My Awesome App Feature"
Display="[SHOW_APP_FEATURE]">
... <!-- Component/ComponentRefs go here -->
</Feature>
This should allow you to accomplish what you're trying to achieve.

WiX Toolset - Hidden property no longer hidden when referenced elsewhere

To hide a property in WiX I'm using
<Property Id="MY_PASSWORD" Hidden="yes" />
Or
<Control Id="Password" Password="yes" Type="Edit" X="30" Y="173" Width="220" Height="18" Property="MY_PASSWORD">
What I haven't found a reliable solution for is how to keep a previously hidden password hidden in a log file after it's been evaluated in:
Another property (e.g. SetProperty, type 51 CustomAction, publish property ina dialog)
A util:XmlFile entry
Is there a way to have a password evaluated without exposing the password once it's used in another WiX element?
In the instances of SetProperty or a type 51 CustomAction, is there a way to hide the original password without needed to hide the rest of the string.
For example set Property="SOME_STRING" Value="password=[MY_PASSWORD];other=[ANOTHER_PROPERTY]", have the property string show up as "password=********;other=the evaluated string"
In the instance of using util:XmlFile, is there any way to hide a password that's evaluated here from showing up in a log file?
This is the solution I came up with, I'm open to better solutions.
In the case of (e.g. SetProperty, type 51 CustomAction, or publish property in a dialog), what I did is create a reference to the property, which I mark as Hidden="yes".
<Property Id="Property_2" Hidden="yes" />
To handle the case: For example set Property="SOME_STRING" Value="password=[MY_PASSWORD];other=[ANOTHER_PROPERTY]", have the property string show up as "password=********;other=the evaluated string"
What I did was write a type 51 CustomAction to create that new property
<CustomAction Id="Set.NewProperty" Property="NewProperty" Value="password=[MY_PASSWORD];other=[ANOTHER_PROPERTY]" />
And add a separate reference to the new property to hide it.
<Property Id="NewProperty" Hidden="yes" />
This worked for me to obscure these details from util:XmlFile.
This solution, in my opinion is less than perfect. Using this method hides the entire string. I would prefer a solution that only hides the password details portion of the string.

WiX InstanceTransforms element produces unresolved reference

I am trying to create a multi-instance setup and followed this question and answers to make it:
Use WIX to install side by side versions of the same IIS site
So I inserted this to my product.wix file
<InstanceTransforms Property="INSTANCEID">
<Instance Id="I01" ProductCode="{68E8345E-0B22-479C-B7A5-7D1B3DC2F835}" ProductName="My Product 01"/>
<Instance Id="I02" ProductCode="{A0E37B8D-12AB-42A0-8F11-9CB08F54B9DE}" ProductName="My Product 02"/>
</InstanceTransforms>
However, when I build my setup project, I get this error:
Unresolved reference to symbol 'Property:INSTANCEID' in section
'Product:{38EEE9BE-86BF-49FB-813B-953DD945575E}'.
Where 38EEE9BE-86BF-49FB-813B-953DD945575E is my main Product Id.
I could not find any reference to this error in the InstanceTransform scope. What am I doing wrong?
UPDATE:
The first thing I tried when I got this error was of course creating a property inside my product with that is called INSTANCEID and some value. However, the error persisted.
I added the Yan's code from his comment below and it compiled. I am not sure what was wrong with my property.
You need a Property element with the Id of your InstanceTranforms/#Property value.

How to read runtime Macro in Wix

I Just want to read a name from a file or read from command line after creating installer file.
I have defined a Macro in my MainProject.wxs file as
< ?define product = "xyz"?>
And I am reading the Macro "product" as follows,
< Registry Action="write"
Id="RegistryEntryId"
Name="InstallDir"
Key="Software\$(var.product)\MyOwnName"
Root="HKLM"
Type="string"
Value="[INSTALLPATH]"
KeyPath="yes"/>
on build time.
But I want to define and read this "product" on runtime after the installer is created, so that I can change the product name according to the file content on runtime, any suggestions would be helpful.
Thanks in Advance.
A macro is handled by a preprocessor. What you request is a variable that can be changed at runtime. You need to use a property.
<Property Id="PROJECTNAME">xyz</Property>
This property can be changed at runtime.
You read the property like this:
[PROJECTNAME]
There are different ways of changing the property. You could do that in a custom action.

How to use a property that was set in a custom action?

I want to set a property in a custom action and use it in the standard custom action "util:User" afterwards. But no matter where I put the property in my wxs-file, I always get "error LGHT0094 : Unresolved reference to symbol"
Details:
In my setup I want to add a new user by using util:User. The user should be added to the group "Power Users" by using util:GroupRef. No Problem so far. Unfortunately the group names are language dependent. In german "Power Users" is "Hauptbenutzer". So I want to look up the well known SID S-1-5-32-547 in a custom action, set a property in this custom action by calling MsiSetProperty and then use the property for util:GroupRef.
As far as I understand, the property must be declared somewhere in the wxs-file.
In the examples I found, the property was never declared as follows (but I also tried that):
<Property Id="TextSID" Value="Power Users" />
In the examples there always was a custom action to set the property, like:
<CustomAction Id="SetTextSID"
Property="TextSID"
Value="Power Users"
Return="check" />
My problem is, that the creation of the user fails to "compile" because the property "TextSID" is not known:
<Component Id="CreateUser" Guid="Some GUID here in my original wxs file">
<util:User Id="UserUser"
Name="User" Password="Password"
CanNotChangePassword="yes" PasswordNeverExpires="yes">
<util:GroupRef Id="TextSID" />
</util:User>
</Component>
I have never done a custom action before and I'm a new to WiX and MSI, so any idea would be very welcome.
Regards
Ralf
Sorry for wasting your time.
I stared at my XML for hours before I posted this question, just to find the answer immediately after my post :-(
My only problem was, that it is not possible to reference to something that isn't there. In this case the "util:Group" was missing.