I have a Windows Phone 8 app which I am porting to Windows-10. The app used .vsix extensions for Windows Phone 8, hence I am trying to create a similar .vsix extension for Universal Windows app as well.
My SDKManifest.xml file is as follows:
<?xml version="1.0"
> encoding="utf-8" ?> <FileList Identity = "XXX.UWP" Version =
> "1.0" DisplayName = "XXX Universal Windows SDK"
> TargetPlatform="UAP" MinVSVersion = "14.0" SDKType="External"
> SupportedArchitectures = "x64;ARM" SupportsMultipleVersions = "Error"
> TargetPlatformMinVersion="10.0.10069.0"
> TargetPlatformVersion="10.0.10069.0"> <File
> Reference="XXX.winmd"
> Implementation="XXX.dll"/> </FileList>
My VSIX Manifest file is
<PackageManifest Version="2.0.0"
xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011">
<Metadata>
<Identity
Id="XXX.UWP"
Version="1.0"
Language="en-US"
Publisher="XXX Inc" />
<DisplayName>XXX SDK for Universal Windows</DisplayName>
<Description>XXX SDK</Description>
<License>license.txt</License>
</Metadata>
<Installation AllUsers="true" Scope="Global">
<InstallationTarget Id="Microsoft.ExtensionSDK"
TargetPlatformIdentifier="Windows Kits"
TargetPlatformVersion="10"
SdkName="XXXSDK.UWP"
SdkVersion="1.0" />
</Installation>
<Assets>
<Asset Type="Microsoft.ExtensionSDK" Path="SDKManifest.xml" />
</Assets>
</PackageManifest>
I have all these xml files along with required dll's in a folder say "myVsix". I then zip this folder to creater "myVsix.zip"
Then I rename this to "myVsix.vsix" to create a .vsix file.
When I try to install this by double clicking on the file, I get the following error:
This VSIX package is invalid because it does not contain the file extension.vsixmanifest at the root. The VSIX file may be corrupted.
This is the error log:
3/3/2016 5:46:30 PM - Microsoft VSIX Installer
3/3/2016 5:46:30 PM - -------------------------------------------
3/3/2016 5:46:30 PM - Initializing Install...
3/3/2016 5:46:30 PM - Microsoft.VisualStudio.ExtensionManager.MissingPackagePartException: This VSIX package is invalid because it does not contain the file extension.vsixmanifest at the root. The VSIX file may be corrupted.
at Microsoft.VisualStudio.ExtensionManager.InstallableExtensionImpl.ReadVSIXManifestFromPackage(Stream vsixStream, CultureInfo preferredCulture)
at Microsoft.VisualStudio.ExtensionManager.InstallableExtensionImpl..ctor(String path, CultureInfo preferredCulture)
at VSIXInstaller.App.InitializeInstall(Boolean isRepairSupported)
at VSIXInstaller.App.InitializeInstall()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
It seems that Visual Studio can't find or read the .vsixmanifest file. It must be misnamed or something else is wrong with it.
Instead of creating the VSIX file by hand, you should create it using the VSIX Project Visual Studio template:
If you can't find it in your Visual Studio copy, you should modify your installation and include the Visual Studio Extensibility Tools:
This will automatically create a correct basic structure of the VSIX and even an editor in Visual Studio for editing the manifest which should make it much easier and more convenient to create a valid VSIX.
Related
Suppose we have a Visual Studio template that we would like to distribute within our organization. This template is hosted on an SVN server. I would like users to be able to point Nuget to the SVN location and get the template installed in the proper location just like any other package. Is this possible?
Is this possible?
We can do it but individuals do NOT recommend it.
How
According to the NuGet document:
Put simply, a NuGet package is a single ZIP file with the .nupkg
extension that contains compiled code (DLLs), other files related to
that code, and a descriptive manifest that includes information like
the package's version number. Developers with code to share create
packages and publish them to a public or private host. Package
consumers obtain those packages from suitable hosts, add them to their
projects, and then call a package's functionality in their project
code. NuGet itself then handles all of the intermediate details.
However, the Visual Studio Template is a file with the .zip extension, which could not be recognized by NuGet. Even if we point NuGet to the SVN location, NuGet still can not recognize it.
To resolve this issue, we have to create a NuGet package to include this Visual Studio Template .zip file, like:
<files>
<file src="TestDemo.zip" target="Tools\TestDemo.zip" />
</files>
Besides, there is another question, when we install this nuget package to the project, this Visual Studio Template .zip file would be downloaded to the \packages folder in the solution folder. We have to move it to the Visual Studio Templates folder.
So, we have to add .targets with copy task in that nuget package to copy zip file to the Visual Studio Templates folder.
The content of .targets file:
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyTemplate" BeforeTargets="Build">
<Message Text="Copy Template to template folder."></Message>
<Copy
SourceFiles="$(SolutionDir)packages\MyTemplatePackage.1.0.0\Tools\TestDemo.zip"
DestinationFolder="$(USERPROFILE)\Documents\Visual Studio 2017\Templates\ProjectTemplates"
/>
</Target>
</Project>
Finally, the .nuspec file like following:
<?xml version="1.0"?>
<package >
<metadata>
<id>MyTemplatePackage</id>
<version>1.0.0</version>
<authors>Tester</authors>
<owners>Tester</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package description</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2018</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="TestDemo.zip" target="Tools\TestDemo.zip" />
<file src="MyTemplatePackage.targets" target="Build\MyTemplatePackage.targets" />
</files>
</package>
Then pack this .nuspec file, add this nuget package to the SVN location, add the SVN location to the nuget package source, you can install this nuget package to the project, and build the project, Visual Studio will download that nuget package and copy .zip file to the Visual Studio Templates folder.
I have created a sample test nuget package and it work fine on my side with Visual Studio 2017, you can test it on VS2017: https://1drv.ms/u/s!Ai1sp_yvodHf2Vax7TzuC6HQUD5w
Why not recommend
Just as you can see above, it is not easy and simple to do this, we have to do a lot of things to create that nuget package. What`s more, in order to get the template we have to create a project and install that package and build the project. It pulls in too many extra operations. Besides, when you change anything in the template, you have to re-create this package and install it.
Since this template is hosted on an SVN server, you can just check it to the Visual Studio template folder, this will be more effective.
Hope this complicated answer helps.
I'm attempting update an existing application so that it will load in Visual Studio 2017 (Enterprise - V15.2 (26430.12)) from Visual Studio 2015 (Enterprise) and having issues with the AjaxMin build task.
In Visual Studio 2015, the AjaxMin build task is found in C:\Program Files (x86)\MSBuild\Microsoft\MicrosoftAjax. Visual Studio 2017 looks for it in C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft. Given that all developers on the team may not have VS2017 Enterprise and we've had issues in the past with developers installing the wrong version, I'd like to have it use the AjaxMin NuGet package referenced in the solution.
There are 3 projects in the solution that use the AjaxMin task. I've updated all of them to have the following import:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
...
<Import Project="$(MSBuildProjectDirectory)\..\..\..\packages\AjaxMin.5.14.5506.26202\tools\net40\AjaxMin.targets" />
<Target Name="BeforeBuild">
<ItemGroup>
<JS Include="..." Exclude="..." />
</ItemGroup>
<ItemGroup>
<CSS Include="..." Exclude="..." />
</ItemGroup>
<AjaxMin Switches="..." JsSourceFiles="#(JS)" JsCombinedFileName="..." CssSourceFiles="#(CSS)" CssCombinedFileName="..." />
</Target>
...
</Project>
However, when the build happens, I receive an error saying it can't find the AjaxMin task in the default build extensions directory:
The "AjaxMin" task could not be loaded from the assembly C:\Program
Files (x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\Microsoft\MicrosoftAjax\AjaxMinTask.dll.
Could not load file or assembly 'file:///C:\Program Files
(x86)\Microsoft Visual
Studio\2017\Enterprise\MSBuild\Microsoft\MicrosoftAjax\AjaxMinTask.dll'
or one of its dependencies. The system cannot find the file specified.
Confirm that the declaration is correct, that the assembly
and all its dependencies are available, and that the task contains a
public class that implements Microsoft.Build.Framework.ITask.
I've used the MSBuild Message Task to output the path and verified that it is correct by navigating to it from the command prompt. I also tried using the UsingTask with no luck there.
Why is Visual Studio not looking for the AjaxMin DLL in the location I specified?
Update:
I moved the import tag for AjaxMin to the top (right under the project tag) and it works now. I don't understand why.
I resolved this issue by installing the .Net 3.5 framework
The issue turned out being another import for another third party build task. It appears that build task alters the build process such that the AjaxMin build task won't work after it. Having the AjaxMin build task after the Microsoft.CSharp.Targets import but before the other third party build task did the trick.
I moved the import tag for AjaxMin to the top (right under the project tag) and it works now. I don't understand why.
If I understand your question correctly, that is because you have two reference sources for the AjaxMinTask.dll, one is the default assembly source:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\MicrosoftAjax, another is the import reference, you will notice that the AjaxMinTask.dll is used in the AjaxMin.targets:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile="AjaxMinTask.dll" TaskName="AjaxMin" />
<UsingTask AssemblyFile="AjaxMinTask.dll" TaskName="AjaxMinBundleTask" />
<UsingTask AssemblyFile="AjaxMinTask.dll" TaskName="AjaxMinManifestTask" />
<UsingTask AssemblyFile="AjaxMinTask.dll" TaskName="AjaxMinManifestCleanTask" />
...
</Project>
So when set the import reference behind your task, MSBuild will use the default assembly source (under the VS2017 installation directory), when you set the import reference before you task, the AjaxMin.targets will rewrite the path of reference source.
I have an extension developed for Visual Studio 2015 that I'd like to start testing for Visual Studio 15.
To try and do this I set the project to launch C:\Program Files (x86)\Microsoft Visual Studio\VS15Preview\Common7\IDE\devenv.exe instead of C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe, keeping the command line arguments set as /rootsuffix Exp. I also set an appropriate install target in the manifest:
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[14.0,15.0)" />
<InstallationTarget Version="[14.0,15.0)" Id="Microsoft.VisualStudio.Pro" />
<InstallationTarget Version="[14.0,15.0)" Id="Microsoft.VisualStudio.Enterprise" />
<InstallationTarget Version="15.0" Id="Microsoft.VisualStudio.Enterprise" />
<InstallationTarget Version="15.0" Id="Microsoft.VisualStudio.Pro" />
<InstallationTarget Version="15.0" Id="Microsoft.VisualStudio.Community" />
(I've tried installation targets of [14.0,16.0) too).
When I debug the project the experimental instance of VS 15 launches ok, however it doesn't have the extension installed.
Is it possible to use Visual studio 2015 to debug an extension for visual studio 15 and if so, how?
What was happening is that the extension was still getting installed to the VS2015 experimental instance. This is because of these lines in the proj file:
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
...
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
Because I was running VS2015 the path to the targets file resolved to the VS2015 one. It's that which defines how the VSIX gets installed to the experimental instance.
I tried changing the reference to the newer VSSDK targets file, however that caused all sorts of errors that I didn't want to wade through.
To test the extension I debugged it (making it install on VS2015 experimental), found the installed extension in the file structure (VS14Exp), copied that to the VS15 folder, debugged again, launching VS15 devenv. experimental instance. At that point breakpoints were being hit etc since it loaded the extension from the folder.
I have a Visual Studio setup project which installs an x64 program that needs the VC++ 14 Redist package.
I selected the options as per image and created a folder structure inside:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\SDK\Bootstrapper\Packages
I have created vcredist_x64 folder which contains:
vcredist_x64.exe
product.xml
en folder
Inside en folder I have:
package.xml
Contents of product.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Product
xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
ProductCode="Microsoft.Visual.C++.11.0.x64"
>
<!-- Defines list of files to be copied on build -->
<PackageFiles>
<PackageFile Name="vcredist_x64.exe" HomeSite="VCRedistExe"/>
</PackageFiles>
<InstallChecks>
<MsiProductCheck Property="VCRedistInstalled" Product="{e46eca4f-393b-40df-9f49-076faf788d83}"/>
</InstallChecks>
<!-- Defines how to invoke the setup for the Visual C++ 11.0 redist -->
<!-- TODO: Needs EstimatedTempSpace, LogFile, and an update of EstimatedDiskSpace -->
<Commands Reboot="Defer">
<Command PackageFile="vcredist_x64.exe"
Arguments=' /q:a '
>
<!-- These checks determine whether the package is to be installed -->
<InstallConditions>
<BypassIf Property="VCRedistInstalled" Compare="ValueGreaterThanOrEqualTo" Value="3"/>
<!-- Block install if user does not have admin privileges -->
<FailIf Property="AdminUser" Compare="ValueEqualTo" Value="false" String="AdminRequired"/>
<!-- Block install on any platform other than x64 -->
<FailIf Property="ProcessorArchitecture" Value="AMD64" Compare="ValueNotEqualTo" String="InvalidOS"/>
<!-- Block install on Vista or below -->
<FailIf Property="VersionNT" Compare="VersionLessThan" Value="6.00" String="InvalidPlatformWinNT"/>
</InstallConditions>
<ExitCodes>
<ExitCode Value="0" Result="Success"/>
<ExitCode Value="3010" Result="SuccessReboot"/>
<DefaultExitCode Result="Fail" FormatMessageFromSystem="true" String="GeneralFailure" />
</ExitCodes>
</Command>
</Commands>
</Product>
Contents of en\package.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Package
xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
Name="DisplayName"
Culture="Culture"
>
<!-- Defines a localizable string table for error messages-->
<Strings>
<String Name="DisplayName">Visual C++ "14" Runtime Libraries (x64)</String>
<String Name="Culture">en</String>
<String Name="AdminRequired">You do not have the permissions required to install Visual C++ Runtime Libraries (x64). Please contact your administrator.</String>
<String Name="InvalidOS">Installation of Visual C++ Runtime Libraries (x64) is supported only on x64 machines.</String>
<String Name="GeneralFailure">A failure occurred attempting to install Visual C++ Runtime Libraries (x64).</String>
<String Name="VCRedistExe">http://go.microsoft.com/fwlink/?LinkID=210622&clcid=0x409</String>
</Strings>
</Package>
When I build the setup project, it gives no errors.
Initially when I didn't have that folder structure along with the xmls I had the error on build:
enable 'Download prerequisites from the same location as my application' in the Prerequisites dialog box, you must download file 'vcredist_x64\vcredist_x64.exe' for item 'Visual C++ "14" Runtime Libraries (x64)' to your local machine. For more information, see http://go.microsoft.com/fwlink/?LinkId=616018.
However I have no errors now. The problem is that it does not install the VC redistributable dependency.
I believe that the productcode and other parameters are not correct in the xmls. Also the VCRedistExe link is for VC++2010 but it does not download anything during setup. However do note that I have the vcredist_x64.exe inside the folder structure which is the VC++14 redist.
Please help me as I have tried many other options as well, and this "official" option does not seem to work (I could not find relevant info Visual C++ Redistributable for Visual Studio 2015).
Either option is fine for me (download from website or download from the same location as my app) as long as the prerequisite is installed.
There is an open issue with MS.
https://connect.microsoft.com/VisualStudio/feedback/details/1604832/vcredist-bootstrapper-packages-in-vs-2015-sdk-arent-working
Here is the link to the 2015 redistributable packages.
https://www.microsoft.com/en-us/download/details.aspx?id=48145
For 32 bit Operating system, check this registry key using regedit
HKLM\Software\Microsoft\GenericBootstrapper\
For 64 bit OS,
HKLM\Software\Wow6432Node\Microsoft\GenericBootstrapper
The path value is the location where you need to place your redistributables.
For example, if u want to place your VC++ 64 bit redistributable(vc_redist.x64.exe)..
if the location is "C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\" in the path value,
place the vc_redist.x64.exe file in "C:\Program Files (x86)\Microsoft SDKs\ClickOnce Bootstrapper\Packages\vc_redistx64\".
Rebuild the project, it works fine now
I am creating an .msi package for the application which has a prerequisite for installation.
I am using the Visual Studio 2005 Bootstrapper for this task.
To this end, I did the following:
Located the folder C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\ and created a folder for my prerequisite (made it same structure as 'dotnetfx'); created the 'product.xml' and 'package.xml' and placed them appropriately. I kept the xml files very simple so far to test the installation:
product.xml
<?xml version="1.0" encoding="utf-8"?>
<Product ProductCode="MyPrereq" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper">
<PackageFiles CopyAllPackageFiles="false">
<PackageFile Name="MyPrereq.exe" />
</PackageFiles>
<InstallChecks>
</InstallChecks>
<Commands Reboot="None">
<Command PackageFile="MyPrereq.exe" EstimatedInstallSeconds="90">
<InstallConditions>
</InstallConditions>
<ExitCodes>
<ExitCode Value="0" Result="Success"/>
<DefaultExitCode Result="Fail" String="GeneralFailure" FormatMessageFromSystem="true" />
</ExitCodes>
</Command>
</Commands>
</Product>
package.xml
<?xml version="1.0" encoding="utf-8"?>
<Package Name="MyPrereq" Culture="Culture" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper">
<Strings>
<String Name="Culture">en</String>
<String Name="DisplayName">MyPrereq</String>
<String Name="GeneralFailure">A fatal error occurred. The installation failed.</String>
</Strings>
</Package>
Now I can add the prerequisite from the list and build my setup project.
The problem:
The build output is the 'setup.exe', the 'MyApp.msi' package, plus the subfolder called 'MyPrereq' which contains 'MyPrereq.exe'.
I would like the build to create a 'setup.exe' and a single 'MyApp.msi', which would contain the 'MyPrereq' inside, with no additional files/directories.
I know that the .NET framework is another prereq for my app, and it is included in the same .msi, so that should be possible somehow.
How can I achieve this?
You can create a self-extracting installer with tools such as IExpress (coming with Windows) containing all files in a single executable (see this SO posting).
You cannot have an MSI file installing its own pre-requisites. First, because Windows Installer itself is a pre-requisite (and must be installed by a non MSI exe) and second because Windows Installer installations are transactional and don't support the chained execution of MSI files. This basically means that one MSI installation cannot start another MSI installation. As a consequence, any pre-requisites must be installed by a separate bootstrapper (by the way, the installation is no longer transactional - the pre-requisites won't get uninstalled if your MSI installation fails).
There seems to be a basic mis-understanding about the bootstrapper mechanism though. The bootstrapper can currently only be generated by Visual Studio or MSBuild. Afaik it is not possible with WiX. Look for the GenerateBootstrapper task in MSBuild (see this SO posting).
I managed to do that with IExpress.
Had to use a small trick, however, which is described here
Creating a bootstrapper for a VS Shell application
Unfortunately, the MSBuild task
doesn't provide the option to have the
configuration resource use
prerequisite installers found in the
target directory, so you must manually
update the appropriate resource file
to remove the hard-coded path that
looks for prerequisites in a
sub-directory of the same name.
Open the Setup.exe program in Visual
Studio's resource editor
Double-click
the resource named, SETUPCFG in the 41
folder
Search for the "Vs Shell\"
string and delete the two occurrences
that appear
Save the resource file
and the Setup.exe executable will be
updated automatically
Run iexpress
Create a new package by following the
IExpress wizard's steps and make sure
to include the following files: The
MyVSShellApplication.msi file The
Setup.exe bootstrapper file The
vs_shell_isolated.enu.exe file
The problem was that bootstrapper puts the prerequisites into a subfolder, and IExpress does not recognise subfolders. Have to be careful while editing 'setup.exe' too, didn't get it correct on the first try.