Creating unsigned ClickOnce deployments with MageUI - deployment

With .Net 3.5 SP1 it is no longer required to sign ClickOnce manifest files. We've incorporated MageUI into our deployment process and would like to deploy some unsigned applications. Mage will let me create an unsigned application manifest. However, it will not let me point the deployment manifest to the unsigned application manifest. It says, "The application manifest is not signed".
Is this a bug? I'm running version 3.5.30729.1; is there a newer version that fixes this? Any ideas for workarounds?

I have the same issue.
Workaround is to add the XML Fragment by hand into the Application Manifest XML

Just a word of warning -- are you deploying this internally-only? Removing the signing is allowed, but not advised. It removes all hashing of the files, and makes your application vulnerable to having the files replaced by malware.

What XML Fragment needs to go into the Application Manifest XML to create unsigned deployment manifests?

Try .Net Frame work 4.0

Related

How can I make Service Fabric package sizes practical?

I'm working on a Service Fabric application that is deployed to Azure. It currently consists of only 5 stateless services. The zipped archive weighs in at ~200MB, which is already becoming problematic.
By inspecting the contents of the archive, I can see the primary problem is that many files are required by all services. An exact duplicate of those files is therefore present in each service's folder. However, the zip compression format does not do anything clever with respect to duplicate files within the archive.
As an experiment, I wrote a little script to find all duplicate files in the deployment and delete all but one of each files. Then I tried zipping the results and it comes in at a much more practical 38MB.
I also noticed that system libraries are bundled, including:
System.Private.CoreLib.dll (12MB)
System.Private.Xml.dll (8MB)
coreclr.dll (5MB)
These are all big files, so I'd be interested to know if there was a way for me to only bundle them once. I've tried removing them altogether but then Service Fabric fails to start the application.
Can anyone offer any advice as to how I can drastically reduce my deployment package size?
NOTE: I've already read the docs on compressing packages, but I am very confused as to why their compression method would help. Indeed, I tried it and it didn't. All they do is zip each subfolder inside the primary zip, but there is no de-duplication of files involved.
There is a way to reduce the size of the package but I would say it isn't a good way or the way things should be done but still I think it can be of use in some cases.
Please note: This approach requires target machines to have all prerequisites installed (including .NET Core Runtime etc.)
When building .NET Core app there are two deployment models: self-contained and framework-dependent.
In the self-contained mode all required framework binaries are published with the application binaries while in the framework-dependent only application binaries are published.
By default if the project has runtime specified: <RuntimeIdentifier>win7-x64</RuntimeIdentifier> in .csproj then publish operation is self-contained - that is why all of your services do copy all the things.
In order to turn this off you can simply add SelfContained=false property to every service project you have.
Here is an example of new .NET Core stateless service project:
<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<IsServiceFabricServiceProject>True</IsServiceFabricServiceProject>
<ServerGarbageCollection>True</ServerGarbageCollection>
<RuntimeIdentifier>win7-x64</RuntimeIdentifier>
<TargetLatestRuntimePatch>False</TargetLatestRuntimePatch>
<SelfContained>false</SelfContained>
</PropertyGroup>
I did a small test and created new Service Fabric application with five services. The uncompressed package size in Debug was around ~500 MB. After I have modified all the projects the package size dropped to ~30MB.
The application deployed worked well on the Local Cluster so it demonstrates that this concept is a working way to reduce package size.
In the end I will highlight the warning one more time:
Please note: This approach requires target machines to have all prerequisites installed (including .NET Core Runtime etc.)
You usually don't want to know which node runs which service and you want to deploy service versions independently of each other, so sharing binaries between otherwise independent services creates a very unnatural run-time dependency. I'd advise against that, except for platform binaries like AspNet and DotNet of course.
However, did you read about creating differential packages? https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-application-upgrade-advanced#upgrade-with-a-diff-package that would reduce the size of upgrade packages after the initial 200MB hit.
Here's another option:
https://devblogs.microsoft.com/dotnet/app-trimming-in-net-5/
<SelfContained>True</SelfContained>
<PublishTrimmed>True</PublishTrimmed>
From a quick test just now, trimming one app reduced the package size from ~110m MB to ~70MB (compared to ~25MB for selfcontained=false).
The trimming process took several minutes for a single application though, and the project I work on has 10-20 apps per Service Fabric project. Also I suspect that this process isn't safe when you have a heavy reliance on dependency injection model in your code.
For debug builds we use SelfContained=False though because developers will have the required runtimes on their machines. Not for release deployments though.
As a final note, since the OP mentioned file upload being a particular bottleneck:
A large proportion of the deployment time is just zipping and uploading the package
I noticed recently that we were using the deprecated Publish Build Artifacts task when uploading artifacts during our build pipeline. It was taking 20 minutes to upload 2GB of files. I switched over the suggested Publish Pipeline Artifact task and it took our publish step down to 10-20 seconds. From what I can tell, it's using all kinds of tricks under the hood for this newer task to speed up uploads (and downloads) including file deduplication. I suspect that zipping up build artifacts yourself at that point would actually hurt your upload times.

VSTS Assembly Version in Release

I've recently started using VSTS to build a Xamarin Forms App for iOS. I have it build using a hosted macos agent and then releasing it to a container in our Azure Blob Storage. The one thing I can solve at the moment, is how to include the Assembly Version in the name of the ipa file?
We're using an Enterprise license, so the ipa doesn't end up on any Store. At the moment I have the App_Name.ipa file and all previous versions App_Name.1.0.0.ipa in the container, however it's always App_Name.ipa that is downloaded.
I thought that it might be an option to parse the AssemblyInfor.cs file and extra the version and then set an environment variable - however I don't seem to be able to access the variable in the Release stage.
Ideally I'd like all this to stay is VSTS, however I don't mind trigger a WebJob to perform some extra tasks, however the version number doesn't appear to be accessible from the ipa file.
Can anyone suggest an approach?
You can use some related extension tasks to get Assembly Version from AssemblyInfor.cs files.
Such as you can use Assembly Info Reader task, and then you can get the Assembly Version by the variable $(AssemblyInfo.AssemblyVersion).

Service Fabric Test-ServiceFabricApplicationPackage powershell crash

After upgrade to sdk 2.5.216 and runtime 5.5.216 Test-ServiceFabricApplicationPackage command works only for complete package. In case of partial app upgrade (some Pkg are removed) it results in "Windows PowerShell has stopped working". I have tested on several computers and several apps. to reproduce:
create test app with 2 services and deploy.
change app version and particular service version.
create package and remove Pkg folder from it for the service without modifications.
connect to Service Fabric and test like Test-ServiceFabricApplicationPackage -ApplicationPackagePath "..path" -ImageStoreConnectionString "fabric:ImageStore"
Maybe somebody was able to overcome this issue? or at least has similar behavior so I'm not alone in Universe.
Thanks!
Alex
Take a look at https://github.com/Azure/service-fabric-issues/issues/259
This is a bug in our code. It happens when a compressed package was uploaded and provisioned in the cluster. Testing a new version of the application fails because settings file was not found in the provisioned version.
We fixed the issue and it will become available in one of our next releases.
Meanwhile, you can skip compression or test the version 2 application package without passing in the image store connection string.
Apologies for the inconvenience!

Prevent user from changing ClickOnce application files after installation

I'm developing a WPF application that I deploy with ClickOnce to a network share on the intranet from which clients can install it.
I need to make sure that the user can't modify any of the application files (especially DLLs and the main executable) on their machine. That is, if any of the application files have changed, the application should refuse to run. I was under the impression that, when using ClickOnce, this was available out of the box and that the application would refuse to start if the file hashes didn't match the manifest.
However, I tried to manually replace the executable or a DLL with a slightly different version after installation and the application still ran fine (executing the modified code).
Does ClickOnce provide what I'm looking for?
How can I enable the functionality?
I'm using a level 2 StartSSL code-signing certificate to sign the application manifest if this matters.
P.S.: just to be sure: I'm talking about the installed application files, not the installation files.
You can sign AND strong name each one of DLLs to prevent tampering but then, doing so has its own pain points when it comes to upgrades and distribution in general. Note that even doing so, doesn't entirely prevent someone from injecting code into your running process. It's a sticky subject.
I recommend going thru this question which already discusses these points in detail. Does code-signing without strong-naming leave your app open to abuse?
I think it will be a fairly manual process.
Doesn't look like the VS2013 deployment tools handle code obfuscation but they do support signing and app permissions. Start with that, then you might have to get the generated manifest as a starting point to build your own with obfuscated assemblies.
MS docs break it into 3 steps: 1. obfuscate, 2. build manifest, 3. manually publish
Here is what MS docs say...
Securing ClickOnce Applications
Deploying Obfuscated Assemblies
You might want to obfuscate your application by using Dotfuscator to prevent others from reverse engineering the code. However, assembly obfuscation is not integrated into the Visual Studio IDE or the ClickOnce deployment process. Therefore, you will have to perform the obfuscation outside of the deployment process, perhaps using a post-build step. After you build the project, you would perform the following steps manually, outside of Visual Studio:
Perform the obfuscation by using Dotfuscator.
Use Mage.exe or MageUI.exe to generate the ClickOnce manifests and sign them. For more information, see Mage.exe (Manifest Generation and Editing Tool) and MageUI.exe (Manifest Generation and Editing Tool, Graphical Client).
Manually publish (copy) the files to your deployment source location (Web server, UNC share, or CD-ROM).

Make deployment ActiveX control with using ClickOnce for Web

I need to make deployment our ActiveX control(two .dll files) through Web with using ActiveX. I saw that deployment .NET application with using ClickOnce is very easy, just need in VS click Build->Publish, but I can't find how I can make it with ActiveX.
Thanks, Roman
That's not possible, the point of ClickOnce is to not alter the configuration of the target machine in any way. Quite the opposite of what is required to get an ActiveX component functioning, it has to be registered and that requires altering the registry with an admin account.