I'm developing a big set of C++ plugin dlls for an external application (using Visual Studio 2017 with the 2015 toolchain if that matters). These plugins in turn share a lot of code, so I put that in it's own common dll file named common.inc (I can't use the .dll extension on it, otherwise the host app mistakes it for a regular plugin). I'd prefer to put this common dll file just next to the other plugin dlls for ease of distributing. The common.inc needs to be pulled in via load-time linking, i.e. not via manual LoadLibrary/GetProcAddress calls (there's just too many entryways into the common.inc to wrap).
This should all work out-of-the-box, were it not for the fact that the host application doesn't play fair here. The host app seems to be using a flat LoadLibrary against the plugins it finds, specifying the full path to the plugins, and doesn't bother to set the current dir to the plugin folder, nor use LoadLibraryEx to specify an additional search path or such. The result is that my plugin dlls can't possibly link up to the common.inc right next to them...
I'd like not to pollute the path env var with the host app's plugin folder, nor do I want to install the common.inc into the host app's install folder or (shudder) windows folder. My solution so far is to use manifest files to direct the Windows loader to common.inc when loading up the plugin dlls, defining a private assembly with common.inc in it.
I got it working, but it's not nice (enough) as-is. I'm currently placing common.inc in a "CommonFolder" folder next to the plugins, and place a CommonFolder.manifest in that folder reffing the common.inc inside it. It's a multi-file assembly set-up of sorts I assume, but only using 1 file. I'd like to morph this in a true single-file assembly to get rid of the extra folder + external manifest file, but I can't seem to get it to work.
What I have so far, which works, is:
plugin.dll's embedded manifest (# ID 2):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="CommonFolder" version="1.0.0.0"></assemblyIdentity>
</dependentAssembly>
</dependency>
<...trustinfo section left out...>
</assembly>
CommonFolder's content:
common.inc without any embedded manifest
CommonFolder.manifest
CommonFolder.manifest in turn contains:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="CommonFolder" version="1.0.0.0" />
<file name="Common.inc" />
</assembly>
What I'm stuck at, which doesn't work, is:
plugin.dll's embedded manifest (# ID 2):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Common.inc" version="1.0.0.0"></assemblyIdentity>
</dependentAssembly>
</dependency>
<...trustinfo section left out...>
</assembly>
common.inc next to plugin.dll, with an embedded manifest (# ID 2):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="Common.inc" version="1.0.0.0"></assemblyIdentity>
<file name="Common.inc"></file>
<...trustinfo section left out...>
</assembly>
I'm probably goofing up big-time here, but I had to give myself a crash course on what manifest files were in the first place. Now that I'm getting more comfortable with manifests, they actually seem quite a simple concept, but the docs I could Google up all seem to fail to convey that in a straight-forward way (often getting waaay too meta about them and thus diluting the actual topic, or only listing all available low-level flags and XML tags without properly relating them to higher-level concepts).
Related
I want to add an assembly reference to many projects.
These projects all include a Common.CSharp.targets file.
Is there any way that I can put the assembly reference in
the included file once? Instead of editing all the other
.csproj files?
This will be better in case we need to change the
reference in the future.
This simple Common.CSharp.targets file below doesn't work
because the reference doesn't appear in Visual Studio 2010
and the project won't compile due to the missing reference.
When I add this reference directly to the .csproj. It works.
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<ItemGroup>
<Reference Include="PostSharp">
</ItemGroup>
</Project>
When my web part is deployed with visual studio or when I install the wsp in test environment, I don't see the module file in the list sharepointServer/Style%20Library/Indices/CSS
But I can access to the file if I type the file name (for example sharepointServer/Style%20Library/Indices/CSS/commonStyle.css).
Elements.xml sample :
<Module Name="Module_Indices" Url="Style Library">
<File Path="Module_Indices\Indices\CSS\commonStyle.css" Url="Watson_Indices/CSS/commonStyle.css" />
</Module>
An idea why I can't see the module files ?
Refer this MSDN Article and Comment in there You will need to add Type="GhostableInLibrary" to the File Tag, it is Mandatory and as your CAML is missing that you are not seeing it in the Library.
<File Path="Module_Indices\Indices\CSS\commonStyle.css" Url="Watson_Indices/CSS/commonStyle.css" Type="GhostableInLibrary" />
So I'm trying to install a web application and I stumbled upon this question: Using WiX to create an IIS virtual directory. When I try to adapt this for my own app, I get an error:
W:\projectlocation\IssInstallationComponents.wxs(6,0): error LGHT0204: ICE18: KeyPath for Component: 'SiteInstallationComponent' is Directory: 'WEBDIRECTORY'. The Directory/Component pair must be listed in the CreateFolders table.
I'm stuck trying to figure this out. Here's what I have in the affected file:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Fragment>
<DirectoryRef Id="WEBDIRECTORY">
<Component Id="SiteInstallationComponent" Guid="MY GUID">
<iis:WebVirtualDir Id="ProductVirtualDirectory" Alias="[PRODUCTVERSION]" Directory="WEBDIRECTORY" WebSite="DefaultWebSite"/>
</Component>
</DirectoryRef>
<iis:WebSite Id='DefaultWebSite' Description='Default Web Site' Directory='WEBDIRECTORY'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
</Fragment>
</Wix>
A couple of notes on my example. First, I know that the GUID is wrong, I removed it from the sample above so that it doesn't get indexed by google and reused by someone looking to figure out something similar. In my code, I have a correct GUID. I also changed the product name to "Product" to avoid any kind of IP issues.
Any ideas on what I need to do to get this code working?
sigh
Okay, I went digging through the interwebs and found the following thread: http://www.mail-archive.com/wix-users#lists.sourceforge.net/msg03483.html
Basically I need to change my component so that it looks like this:
<Component Id="SiteInstallationComponent" Guid="MY GUID">
<CreateFolder />
<iis:WebVirtualDir Id="ProductVirtualDirectory" Alias="[PRODUCTVERSION]" Directory="WEBDIRECTORY" WebSite="DefaultWebSite"/>
</Component>
I love Wix, but sometimes it drives me crazy.
Thought I'd add a bit to this. In my case I needed to modify a config file as part of a patch with an XmlConfig action. I ran into the original problem and also tried to work around it by just sticking a CreateFolder element in there. But there's a hitch with that. If your component is part of a patch, putting a CreateFolder entry in there makes it not uninstallable. That means you can't roll back the patch.
What I ended up doing was creating a different KeyPath for the component. I gave it a registry key as the KeyPath and it stopped bothering me about the CreateFolder entry. This means that it will do whatever you want it to do on install and uninstall and use the registry key you gave it to track whether or not the component is installed.
<RegistryKey Root="HKLM" Key="[REGISTRYKEY]\Settings\[TITLE]" Action="createAndRemoveOnUninstall">
<RegistryValue Action="write" Type="integer" Name="MACHINEMEMORYLIMIT" Value="1" KeyPath="yes"/>
</RegistryKey>
(In this case REGISTRYKEY and TITLE are two properties we passed into the installer)
I have this feature
<?xml version="1.0" encoding="utf-8"?>
<Feature Id="c54f20d8-1ad1-49b8-aff7-2c874dd2f45a"
Title="MyCompany Content Types"
Description="Content Types required for MyCompany Provided Applications and Functionality"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="siteColumns.xml"/>
</ElementManifests>
</Feature>
Here is the contents of siteColumns.xml
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field
ID="{1F343F02-22D9-45b8-A2A8-CEB2619A28C4}"
Name="AllowSubstDelivery"
DisplayName="AllowSubstDelivery"
Type="Boolean"
Format="TRUE"
Group="MyCustomGroup"
/>
</Elements>
The feature installs and activates, without producing an error, but the siteColumn is nowhere to be found, any ideas why this site column is not visible?
I checked the logs, no errors reported either.
Hmmm... it looks like you have done everything correctly. Did you copy and paste the ID for the Field from anywhere? If so, the ID may already be in use causing your Field provision to be ignored.
I find the best way to create a Feature defining Site Columns and Content Types is to prototype everything using the Web interface and then copy and paste the generated CAML into your Visual Studio projects. I recorded a short video demonstrating the process that you may find valuable.
SharePoint Site Columns and Content Types via a Feature
What does Format="TRUE" mean?
Doesn't look like it's according to documentation.
Field Element Documentation doesn't tell you much about those properties, however there is much in common with FieldRef element and it has documentation about Format attribute.
Maybe you wanted to use DefaultValue attribute?
I'm trying to deploy multiple web parts as part of the same feature. SharePoint itself seems to do this quite happily by specifying multiple File elements in a single Module element (see C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\SearchWebParts); in my case, only the first web part is added to the Web Parts gallery, albeit to the Miscellaneous group instead of the group specified in the Property element.
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="WebPartPopulation" Url="_catalogs/wp" Path="WebParts">
<File Url="Test1.webpart" Type="GhostableInLibrary">
<Property Name="Group" Value="MyGroup" />
</File>
<File Url="Test2.webpart" Type="GhostableInLibrary">
<Property Name="Group" Value="Mygroup" />
</File>
</Module>
</Elements>
My .webpart files are located in the same directory as the elements file; I tried setting Path="" on the Elements element but nothing gets deployed then. Switching around the two File elements deploys Test2.webpart instead of Test1 and Test1.webpart is not added on feature activation. Adding a single File per Module does work but that means duplicating the Module elements.
I'm self-closing the Property elements but that's surely not a sin?? What am I doing wrong?
The above would seem to be correct: after a reboot and a sleep, both web parts ended up in their proper groups when I came back to it the next day. It's surprising how often I find a reboot fixes up weird SharePoint things like this that even and iisreset won't touch. Maybe other services that should be reset/caching these things?