Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom attribute to Bundle project (Bootstrapper) #137

Closed
lord2kim opened this issue Aug 26, 2017 · 13 comments
Closed

Add custom attribute to Bundle project (Bootstrapper) #137

lord2kim opened this issue Aug 26, 2017 · 13 comments

Comments

@lord2kim
Copy link

I'am trying to add custom attribute dep:ProviderKey = 01234567-8901-2345-6789-012345678901 to Bundle tag of bootstrapper .wxs file (I hope this help me hardcode GUID value for bootstrapper installer):

...

var productMsi = Compiler.BuildMsi(project);

var bootstrapper =
                new Bundle($"Application",
                    new PackageGroupRef("NetFx40Web"),
                    new MsiPackage(productMsi) { Vital = true, Id = "MyProductPackageId", DisplayInternalUI = false })
                { AttributesDefinition = "dep:ProviderKey = 01234567-8901-2345-6789-012345678901" };

bootstrapper.IncludeWixExtension(@"WixDependencyExtension.dll", "dep", "http://schemas.microsoft.com/wix/DependencyExtension");

...

I'am tried use and Attributes property and AttributesDefinition property and has the same result:
The Bundle element contains an unexpected attribute 'WixSharpCustomAttributes'.

WixSharpCustomAttributes="dep:ProviderKey=6f330b47-2577-43ad-9095-1861bb258891"

What I do wrong ? How I can add custom attribute to Bundle project ?

@oleg-shilo
Copy link
Owner

oleg-shilo commented Aug 27, 2017

You cannot use AttributesDefinition for that as the column character is reserved as a separator for parent element in the attribute name: "Component:SharedDllRefCount=yes".

Thus, as in any other case of XML ambiguity, you will need to handle the problem an XML way:

bootstrapper.IncludeWixExtension("WixDependencyExtension.dll", "dep", "http://schemas.microsoft.com/wix/DependencyExtension");
...
bootstrapper.WixSourceGenerated += (doc) =>
{
    var dep = doc.Root.GetNamespaceOfPrefix("dep");
    doc.Root.Select("Bundle").Add(new XAttribute(dep + "ProviderKey", "01234567-8901-2345-6789-012345678901"));
};

It's possible to extend the current "add attribute" algorithm to support XML namespeces by introducing an alternative delimiter to indicate the namespace as opposite to the parent element. Though the best candidate "column" is already taken :(

The ideal solution would be:

project.AttributesDefinition="Component|SharedDllRefCount=yes";
// and
project.AttributesDefinition="dep:ProviderKey=01234567-8901-2345-6789-012345678901";

And because ':' is taken (and already in use for quite some time) a less intuitive second delimiter will need to be introduced. Something like this:

project.AttributesDefinition="Component:SharedDllRefCount=yes";
// and
project.AttributesDefinition="dep'ProviderKey=01234567-8901-2345-6789-012345678901";
// or
project.AttributesDefinition="{dep}ProviderKey=01234567-8901-2345-6789-012345678901";

This is what I haven't decided yet and would appreciate the community feedback.

Anyway I am marking this issue as a feature requests so the namespace support comes in one or another way.

@lord2kim
Copy link
Author

@oleg-shilo, thank you very much. This is working for me.

But looks like this doesn't resolve mine problem. Maybe you can help me with it ?

When I've install my application from bootstrapper installer, I have 2 new installed programms: mine program with ID which is not same as I set for .msi package; and another for bootstrapper installer.

Uninstall shortcut has Target attribute for program (not for bootstrapper installer). Maybe I can get ID value for bootstrapper installer from WPF code ? (for change Uninstall shortcut to shortcut for bootstrapper installer)
Or maybe there is another way for do it ?

For example:
In current time Uninstall.lnk has follow target: <C:\Windows\System32\msiexec.exe /x {GUID_FOR_MSI_PACKAGE}>
I wan set it to follow: <C:\ProgramData\Package Cache{GUID_FOR_BOOTSTRAPPER_INSTALLER}\Application.exe>

@oleg-shilo
Copy link
Owner

I am not sure if you can extract the GUID from the bootstrapper app. Though you definitely can from MSI.

Also keep in mind that you have full control over MSI identities (see this doc section). Meaning that you can specify your Product and Upgrade code (that appears in Control Panel) directly in your project definition.

@lord2kim
Copy link
Author

@oleg-shilo, ok thank you.
In either case, I need a bootstrapper GUID.

I did not think about a more optimal option than parse registry branch for Uninstall programs and search installed bootstrapper application. After that, change the Target property in the Uninstall.lnk file to UninstallString from the registry.

@oleg-shilo
Copy link
Owner

BTW, that bootstrapper GUID that you see in Control Panel is most likely the "bootstrapper.UpgradeCode" that you assigned in the project definition.

@lord2kim
Copy link
Author

@oleg-shilo, looks like no.
The fact is that I don't see any GUID values in the Unistall registry branch, which I assigned to GUID & UpgradeCode to MSI package and UpgradeCode of bootstrapper.

@oleg-shilo
Copy link
Owner

I expect you to see no project.GUID in the registry. Correct. However there should be project.UpgradeCode.

In case of any uncertainty have a look at your MSI in Orca (MSI viewer). It will let you see directly in the MSI tables.
...
Sorry, I will not be able to respond as I will be unavailable for a week or so.

@lord2kim
Copy link
Author

@oleg-shilo. ok thank you Oleg.
No, I didn't see UpgradeCode value in registry.

I will look. Maybe I'll find something I need :)

@oleg-shilo
Copy link
Owner

oleg-shilo commented Aug 29, 2017

Give it a try to Orca. Then you will know for sure the all IDs you should be looking for:

image

oleg-shilo added a commit that referenced this issue Sep 1, 2017
    - Added support for XML namespace prefix in 'AttributesDefinition`
    `AttributesDefinition = "{dep}ProviderKey = 01234567-8901-2345-6789-012345678901"`
@raghuma4
Copy link

raghuma4 commented Sep 21, 2018

Hi,

I am trying to add custom attribute to MsiPackage element in Bundle using the wix extensions. After adding the custom attribute to my .xsd file and making necessary changes to CompilerExtension.cs and PreprocessorExtension.cs, still candle.exe is throwing an error saying that "The MsiPackage element contains an unexpected attribute error:Custom attribute"

Any idea to resolve this error ?

Thanks for your help

oleg-shilo added a commit that referenced this issue Sep 22, 2018
* Issue #137: Add custom attribute to Bundle project (Bootstrapper)
* Issue #452: Component Id generation for RegValue does not take RegValue.Id into account
* An empty directory remains after the uninstall #464
* `AutoElements.SupportEmptyDirectories` default setting to `Automatic` is made obsolete, though is not removed yet. In the future releases `AutoElements.SupportEmptyDirectories` will be enabled by default.
* `File.OverwriteOnInstall` now triggers insertion of `<RemoveFile On=both ...>` instead of `<RemoveFile On=install ...>`. To avoid upgrade problems with individual files.
* Fixed the problem with `project.ActualInstallDirId` being potentially undefined
* ResilientPackage improvements
  - Create a hard link to the local package instead of the original MSI.
  - Added deterministic assignment of installdir id in `EnableResilientPackage`
* Bootstrapper_UI sample is updated to show how to pass user input from BA to MSI package.
@oleg-shilo
Copy link
Owner

First of all, a few words about the original problem reported in this thread.

Unfortunately the feature (support for custom attributes) has been implemented but only partially. Thus Project and its content got the feature integrated but Bundle did not.

The very latest release v1.9.2 addresses the issue and now you can add custom attributes to the Bundle:

bootstrapper.IncludeWixExtension(@"WixDependencyExtension.dll", "dep", "http://schemas.microsoft.com/wix/DependencyExtension");
bootstrapper.AttributesDefinition = "{dep}ProviderKey=01234567-8901-2345-6789-012345678901";

This feature is yet to be extended to Packages but non custom attributes are already supported by all entities across the system.

If you find that you cannot add custom attribute with WixSharp default functionality you can always inject then via xml-injection mechanism (see InjectXML sample).


Now, about your problem.

I am not sure I follow. What are those CompilerExtension.cs and PreprocessorExtension.cs files?

Anyway, if you add attribute from the custom namespace you typically need to add this namespace via "WixExtension". This is what that bootstrapper.IncludeWixExtension call does.

@raghuma4
Copy link

raghuma4 commented Sep 24, 2018

Hello,

I am sorry to confuse you. I have created my own extension schema and added custom elements to Bundle element like

<Bundle>
     <mySchema:Element1 attr1="value1"
                                          attr2="value2"/>
</Bundle>

But I would also like to add custom attribute to existing MsiPackage element in Bundle like

<MsiPackage  Id="p1"
                        mySchema:CustomAttr1="value" />

I have added to custom attribute to my xsd file using <xs:attribute name="CustomAttr1".... />

As per wix documentation on MsiPackage element Any Attribute (namespace='##other' processContents='lax') Extensibility point in the WiX XML Schema. Schema extensions can register additional attributes at this point in the schema. The extension's CompilerExtension.ParseAttribute() method will be called with the package identifier in contextValues["PackageId"].
Reference : http://wixtoolset.org/documentation/manual/v3/xsd/wix/msipackage.html

Unfortunately I am getting error saying that MsiPackage contains unexpected element mySchema:CustomAttr1. The wix schema is not recognizing my custom attribute (CustomAttr1).

Please provide your suggestions on this ? Thanks in Advance

@oleg-shilo
Copy link
Owner

If compiler says that it cannot recognize your namespace extension and the name of the namespace is correct (I assume mySchema) then it simply means that the compiler does not know where your namespace is defined.

For example the assembly that defines DependencyExtension namespace ('WixDependencyExtension.dll') is added as below:

bootstrapper.IncludeWixExtension(@"WixDependencyExtension.dll", "dep", "http://schemas.microsoft.com/wix/DependencyExtension");

Something similar needs to be done for your assembly as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants