![](/img/trans.png)
[英]ClickOnce Deployment Error: different computed hash than specified in manifest
[英]ClickOnce deployment is leaving multiple versions (yes, more than two)
我有一個ClickOnce應用程序,它在我的磁盤上保留了所有舊版本。 這是一個經常更新的內部企業應用程序,因此對於快速膨脹我們的備份大小來說,這是一場災難。
根據文檔和其他 Stack Overflow 問題,應該只將當前和以前的版本保留在磁盤上。 但是,每次我部署項目和升級客戶端時,我都會得到所有 EXE、DLL 和數據文件的另一個副本。 我沒有對應用程序進行任何更改,只是在 Visual Studio 中再次推送部署。
我該如何解決這個問題?
該問題似乎在 Windows 7 和 Windows XP 以及 64 位和 32 位 Windows 上都會發生。
我已經對安裝版本的文件夾做了一個差異,以下文件是不同的:
MyApp.exe.manifest
MyApp.exe.cdf-ms
MyDll1.cdf-ms
MyDll2.cdf-ms
沒有實際的可執行文件是不同的,也沒有MyApp.manifest
、 MyDll1.manifest
等。
替代方案怎么樣。 在運行時查找包含我的應用程序的其他文件夾並刪除它們是否安全? 這會破壞任何東西嗎?
ClickOnce 只是一個明顯的神秘黑匣子嗎?
我想我終於想到了這個。 對於某些未知(並且不可接受,坦率地說)的原因,如果較新的版本正在運行,舊版本的清理將不會發生 - 它只是無聲地失敗。
清理嘗試在舊版本退出時運行,但由於我重新啟動了應用程序,新版本已經啟動,阻止清理。
另外,請注意其他答案中提到的“清道夫服務”似乎是完全捏造。 我沒有找到任何此類服務的文檔,也沒有任何證據表明它正在運行。 清理似乎是作為clickonce更新過程的一部分內聯發生的。
清道夫服務是ClickOnce引擎的一部分; 它會自動運行,而不是您可以直接訪問的內容。 它應該到來並清理舊版本。
關於min版本的問題。 如果您部署新版本並將min min required版本設置為新版本#,它是否將應用程序更新為該版本? 然后將前一個(s)留在磁盤上?
你能看到任何模式嗎? 它正在緩存的部署數量是否有限制?
還有一些關於影子文件夾的東西,它在我的記憶中徘徊; 文件不是真的存在。 我會做一些研究,看看我的筆記,看看我能找到什么。
它是什么類型的應用程序? 的WinForms / WPF / VSTO?
當你說它是緩存文件夾時,它是哪個文件夾? 例如,對於winforms應用程序,為每個版本創建了兩個文件夾(xxxxtion ...和xxxxexe ......或類似的東西)加上一堆文件夾 - 一個用於部署中包含的每個程序集 - 這些是緩存版本的程序集,以便每次都沒有更改時不必下載它們。 你看到的是xxxxtion和xxxxexe文件夾的倍數嗎?
你現在正在檢查嗎? 一天左右后它們甚至都沒有消失? ClickOnce清道夫服務應該出現並刪除舊版本。 如果您將最新版本作為必需更新推送,是否會刪除其他版本? (為此,請在“更新”對話框中將所需的最低版本設置為您正在部署的同一版本)。
這是在客戶端清除舊 ClickOnce 版本的功能。
在我的機器上,我釋放了 6Gb 的空間。 我什至不想知道舊版本組織使用的總空間......
/// <summary>
/// Delete directories of old ClickOnce versions leaving newest in place.
/// NOTE: Users have privileges for installing and deleting folders in their local deployment directory.
/// </summary>
public static void CleanOldVersions()
{
string path = AppDomain.CurrentDomain.BaseDirectory;
int lastSlash = path.LastIndexOf(@"\");
path = path.Substring(0, lastSlash );
lastSlash = path.LastIndexOf(@"\");
path = path.Substring(0, lastSlash);
var dirInfo = new DirectoryInfo(path);
var directories = dirInfo.EnumerateDirectories()
.OrderByDescending(d => d.CreationTime)
.ToList();
List<string> DeletedAppIDs = new List<string>();
foreach (DirectoryInfo subDirInfo in directories)
{
int first_ = subDirInfo.Name.IndexOf("_");
if (first_ < 0) continue;
string appID = subDirInfo.Name.Substring(first_+1, 21);
if (DeletedAppIDs.Contains(appID)) continue;
var subdirectories = subDirInfo.Parent.EnumerateDirectories()
.Where(d => d.Name.Contains(appID))
.OrderByDescending(d => d.CreationTime)
.ToList();
bool isNewest = true;
foreach (DirectoryInfo subDirName in subdirectories)
{
if (isNewest)
{
isNewest = false;
}
else
{
try
{
SetAttributesToNormal(subDirName); //Set attributes to normal to prevent failures
subDirName.Delete(true);
if (!DeletedAppIDs.Contains(appID))
{
DeletedAppIDs.Add(appID);
}
}
catch (UnauthorizedAccessException)
{
//Catch unauthorized access to prevent exit if a previous version has any open dll
}
}
}
}
}
private static void SetAttributesToNormal(DirectoryInfo dir)
{
foreach (var subDir in dir.GetDirectories())
SetAttributesToNormal(subDir);
foreach (var file in dir.GetFiles())
{
file.Attributes = FileAttributes.Normal;
}
}
可以像這樣在啟動時調用它:
private async void InitTasks()
{
try
{
await Task.Run(() => CleanOldVersions());
}
catch (Exception ex)
{
//Error handling
}
}
來自文檔:
在線托管的ClickOnce應用程序受限於ClickOnce緩存大小的配額占用的空間量受到限制。 緩存大小適用於所有用戶的在線應用程序; 單個部分受信任的在線應用程序僅限於占用一半的配額空間。 已安裝的應用程序不受緩存大小的限制,也不會計入緩存限制。 對於所有ClickOnce應用程序,緩存僅保留當前版本和先前安裝的版本。 默認情況下,客戶端計算機具有250 MB的在線ClickOnce應用程序存儲空間。 數據文件不計入此限制。 系統管理員可以通過更改注冊表項HKEY_CURRENT_USER \\ Software \\ Classes \\ Software \\ Microsoft \\ Windows \\ CurrentVersion \\ Deployment \\ OnlineAppQuotaInKB來擴大或減少特定客戶端計算機上的此配額,這是一個表示緩存大小的DWORD值,以千字節為單位。 例如,為了將緩存大小減小到50 MB,您可以將此值更改為51200
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.