ClickOnce. While the concept is great, the execution is not fantastic. Try creating a separate version, downloadable from your testing URL. But that’s a story for another day.
ClickOnce allows continuous updates delivered to your clients, something any Windows client developer would like. However, after distributing your application, many developers are plagued with an error about a file or the applicatoin having a “different computed hash than specified in manifest”.
TL; DR: Merging branches with Git changes something about the files. As specified in this SO answer, add a .gitattributes
file with these lines:
*.vsto binary
*.deploy binary
*.manifest binary
ClickOnce computes hashes over all files, and any .exe
or .dll
files are appended with a .deploy
extension. The .manifest
file lists all SHA1 hashes for all files, you can check these using this code:
using System;
using System.Security.Cryptography;
using System.IO;
namespace FileHashSample
{
public class FileHash
{
public FileHash()
{
return;
}
public string ComputeHash(string filePath)
{
string filePathNormalized = System.IO.Path.GetFullPath(filePath);
SHA1 sha = new SHA1Managed();
FileStream fs = new FileStream(filePathNormalized, FileMode.Open, FileAccess.Read);
byte[] byteHash = sha.ComputeHash(fs);
fs.Close();
return Convert.ToBase64String(byteHash, 0, byteHash.Length);
}
public static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("Please Enter a File Path");
return;
}
string filePath = System.IO.Path.GetFullPath(args[0]);
FileHash objFileHash = new FileHash();
Console.WriteLine("File Path is {0}", filePath);
Console.WriteLine("File Hash is {0}", objFileHash.ComputeHash(filePath));
return;
}
}
}
(From this MSDN question)
Finally, this .manifest
file is hashed and the hash is noted in your .application
file. If any of these files changes, the hashes need to be recomputed using Mage.exe
and Mageui.exe
. And alas, merging Git branches sometimes changes the .manifest
file slightly, resulting in a different hash. However, as you didn’t update the hash for the .manifest
file in the .application
file, installation fails with an error about a “different computed hash than specified in manifest”. The solution? Tell Git not to change the .manifest
file, using this SO answer: Add a .gitattributes
file containing the following lines:
*.vsto binary
*.deploy binary
*.manifest binary
If, after doing this, your application is still complaining about a different hash on a .config
file, don’t mark that as binary as well: You might like to diff these! Instead, consider disabling hashing for .config
files: In Visual Studio, open Properties, go to Publish and click Application Files. On the screen that appears, you can disable hashing in the last column. However, for DLLs, I’d recommend keeping these hashes, disabling it for just one config file should be acceptable.