當您嘗試更新 Visual Studio 2005 ClickOnce 應用程式,用來簽署安裝在憑證過期後,收到錯誤訊息

文章翻譯 文章翻譯
文章編號: 925521 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

徵狀

當想您用來簽署安裝在憑證過期後更新 Microsoft Visual Studio 2005 ClickOnce 應用程式會收到下列錯誤訊息:
部署識別不符合訂閱。

發生的原因

之所以發生這個問題,是因為您必須可以使用數位認證簽署所有的 ClickOnce 部署。您不能使用過期的憑證來簽署 ClickOnce 應用程式。若要將更新部署至應用程式具有過期的憑證,您必須指定應用程式新的憑證。當新的憑證不符合原始憑證時,您會收到錯誤訊息本文 < 徵狀 > 一節所述。

解決方案

如果要解決這個問題,使用下列方法之一。

方法 1

更新 ClickOnce 應用程式安裝至 [Microsoft 用戶端電腦.NET Framework 2.0 Service Pack 1 (SP1) 或更新版本。

Windows Vista

套用.NET Framework 3.5 或.NET Framework 3.5 SP 1。

附註.NET Framework 3.5 包含許多新功能,建置在.NET Framework 2.0 時逐漸和 3.0。.NET Framework 3.5 包括.NET Framework 2.0 SP1 和.NET Framework 3.0 SP1。

下列檔案是可以從 Microsoft 下載中心 」 下載:

摺疊此圖像展開此圖像
Download
Download the .NET Framework 3.5 package now.

摺疊此圖像展開此圖像
Download
Download the .NET Framework 3.5 Service Pack 1 package now.

如需有關如何下載 Microsoft 支援檔案的詳細資訊,按一下 [下列面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項]:
119591如何從線上服務取得 Microsoft 的支援檔案
Microsoft 已掃描這個檔案有無病毒。Microsoft 使用已張貼檔案的日期中的 [可用的最新病毒偵測軟體。檔案儲存在安全性強化的伺服器上,協助防止未經授權的任何變更的檔案。

Windows XP

套用.NET Framework 2.0 SP1 或.NET Framework 2.0 Service Pack 2 (SP2)。

從 「 Microsoft 下載中心 」 下載下列檔案有:

摺疊此圖像展開此圖像
Download
Download the .NET Framework 2.0 Service Pack 1 (x86) package now.

摺疊此圖像展開此圖像
Download
Download the .NET Framework 2.0 Service Pack 1 (x64) package now.

摺疊此圖像展開此圖像
Download
Download the .NET Framework 2.0 Service Pack 2 package now.

如需有關如何下載 Microsoft 支援檔案的詳細資訊,按一下 [下列面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項]:
119591如何從線上服務取得 Microsoft 的支援檔案
Microsoft 已掃描這個檔案有無病毒。Microsoft 使用已張貼檔案的日期中的 [可用的最新病毒偵測軟體。檔案儲存在安全性強化的伺服器上,協助防止未經授權的任何變更的檔案。

方法 2

解除安裝由使用過期的憑證簽署 ClickOnce 應用程式。然後,重新安裝更新的 ClickOnce 應用程式使用新的憑證。

方法 3

建立命令列的組件來更新憑證。 要這麼做,請您執行下列步驟。

Microsoft 僅,為了說明提供程式設計範例,不提供任何明示或默示的保證。這包括,但不限於適售性或適合某特定用途之默示擔保責任。本文假設您已熟悉使用我們所示範的程式設計語言以及建立和偵錯程序所使用的工具。Microsoft 技術支援工程師可以協助解釋特定程序的功能。不過,不會修改這些範例以提供附加功能或建構程序,以符合您特定需求。
  1. 在 Visual 的 Studio 2005 中按一下 [檔案] 功能表上的 [新增],然後按一下 [專案]。
  2. 按一下 [Visual C++ 按一下 [Win32 主控台應用程式、 在 [名稱] 方塊中鍵入 RenewCert 然後再按一下 [確定]
  3. Win32 應用程式精靈] 對話方塊中,按一下 [完成]。
  4. In the RenewCert.cpp file, replace the existing code with the following code:
    #include "stdafx.h"
    
    void ReadPFXFile(LPCWSTR fileName, CRYPT_DATA_BLOB *pPFX)
    
    {
    
                HANDLE hCertFile = NULL;
    
                DWORD cbRead = 0;
    
                DWORD dwFileSize = 0, dwFileSizeHi = 0;
    
                hCertFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
    
                dwFileSize = GetFileSize(hCertFile, &dwFileSizeHi);
    
                pPFX->pbData = (BYTE *) CryptMemAlloc(dwFileSize*sizeof(BYTE));
    
                pPFX->cbData = dwFileSize;
    
                ReadFile(hCertFile, pPFX->pbData, pPFX->cbData, &cbRead, NULL);
    
                CloseHandle(hCertFile);
    
    }
    
    void GetPrivateKey(CRYPT_DATA_BLOB pPFX, LPCWSTR szPassword, HCRYPTPROV *hCPContext)
    
    {
    
                HCERTSTORE hCertStore = NULL;
    
                PCCERT_CONTEXT hCertContext = NULL;
    
                DWORD dwKeySpec = AT_SIGNATURE;
    
                BOOL bFreeCertKey = TRUE;
    
                hCertStore = PFXImportCertStore(&pPFX, szPassword, CRYPT_EXPORTABLE);
    
                hCertContext = CertEnumCertificatesInStore(hCertStore, NULL);
    
                CryptAcquireCertificatePrivateKey(hCertContext, 0, NULL, hCPContext, &dwKeySpec, &bFreeCertKey);
    
                CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
    
    }
    
    void PrintContainerName(HCRYPTPROV hCPContext)
    
    {
    
                DWORD containerNameLen = 0;
    
                CHAR *szContainerName = NULL;
    
                CryptGetProvParam(hCPContext, PP_CONTAINER, NULL, &containerNameLen, 0);
    
                szContainerName = (CHAR *)CryptMemAlloc(sizeof(BYTE)*containerNameLen);
    
                CryptGetProvParam(hCPContext, PP_CONTAINER, (BYTE *)szContainerName, &containerNameLen, 0);
    
                printf("This certificate's container name is: %s", szContainerName);
    
    }
    
    void MakeNewCert(HCRYPTPROV hCPContext, LPCWSTR szCertName, LPCWSTR szPassword, CRYPT_DATA_BLOB *pPFX)
    
    {
    
                CERT_NAME_BLOB certNameBlob = {0,NULL};
    
                PCCERT_CONTEXT hCertContext = NULL;
    
                SYSTEMTIME certExpireDate;
    
                HCERTSTORE hTempStore = NULL;
    
                CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szCertName, CERT_OID_NAME_STR, NULL, NULL, &certNameBlob.cbData, NULL);
    
                certNameBlob.pbData = (BYTE *)CryptMemAlloc(sizeof(BYTE)*certNameBlob.cbData);
    
                CertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szCertName, CERT_OID_NAME_STR, NULL, certNameBlob.pbData, &certNameBlob.cbData, NULL);
    
                GetSystemTime(&certExpireDate);
    
                certExpireDate.wYear += 5;
    
                hCertContext = CertCreateSelfSignCertificate(hCPContext, &certNameBlob, 0, NULL, NULL, NULL, &certExpireDate, NULL);
    
                hTempStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_CREATE_NEW_FLAG, 0);
    
                CertAddCertificateContextToStore(hTempStore, hCertContext, CERT_STORE_ADD_NEW, NULL);
    
                PFXExportCertStoreEx(hTempStore, pPFX, szPassword, NULL, EXPORT_PRIVATE_KEYS);
    
                pPFX->pbData = (BYTE *)CryptMemAlloc(sizeof(BYTE)*pPFX->cbData);
    
                PFXExportCertStoreEx(hTempStore, pPFX, szPassword, NULL, EXPORT_PRIVATE_KEYS);
    
                CryptMemFree(certNameBlob.pbData);
    
                CertCloseStore(hTempStore, CERT_CLOSE_STORE_FORCE_FLAG);
    
                CertFreeCertificateContext(hCertContext);
    
    }
    
    void WritePFX(CRYPT_DATA_BLOB pPFX, LPCWSTR szOutputFile)
    
    {
    
                HANDLE hOutputFile = NULL;
    
                DWORD cbWritten = 0;
    
                hOutputFile = CreateFile(szOutputFile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
                WriteFile(hOutputFile, pPFX.pbData, pPFX.cbData, &cbWritten, NULL);
    
                CloseHandle(hOutputFile);
    
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    
    {
    
                LPCWSTR szCertFileName = NULL;
    
                CRYPT_DATA_BLOB pPFX;
    
                LPCWSTR szPassword = NULL;
    
                HCRYPTPROV hCPContext = NULL;
    
                LPCWSTR szCertName = L"CN=NewCert";
    
                CRYPT_DATA_BLOB pPfxOutputBlob = {0,NULL};
    
                LPCWSTR szOutFile = NULL;
    
                // Parse the command line.
    
                if(argc == 1)
    
                {
    
                            printf("renewcert <PFX File> <new cert filename> <new cert friendly name> [optional]<password>\n");
    
                            printf("Example: renewcert oldcert.pfx newcert.pfx \"CN=MyNewCert\" MySuperSecretPassword");
    
                            return 0;
    
                }
    
                if(argc >= 2)
    
                            szCertFileName = argv[1];
    
                if(argc >= 5)
    
                            szPassword = argv[4];
    
                // Uncomment this block to add <new cert filename> and <new cert friendly name> as parameters
    
                // NOTE: <new cert friendly name> must be of format "CN=<name>"
    
                if(argc >= 3)
    
                            szOutFile = argv[2];
    
                if(argc >= 4)
    
                            szCertName = argv[3];
    
                ReadPFXFile(szCertFileName, &pPFX);
    
                GetPrivateKey(pPFX, szPassword, &hCPContext);
    
                //PrintContainerName(hCPContext);
    
                // Uncomment this section to make a new PFX rather than just printing the container name.
    
                // Make sure you also uncomment the command line parameter section above.
    
                MakeNewCert(hCPContext, szCertName, szPassword, &pPfxOutputBlob);
    
                WritePFX(pPfxOutputBlob, szOutFile);
    
                // Clean up.
    
                CryptReleaseContext(hCPContext, 0);
    
                CryptMemFree(pPfxOutputBlob.pbData);
    
                CryptMemFree(pPFX.pbData);
    
                return 0;
    
    }
    
  5. stdafx.h] 檔案中以下列的程式碼取代現有的程式碼:
    // stdafx.h : include file for standard system include files,
    
    // or project specific include files that are used frequently, but
    
    // are changed infrequently.
    
    //
    
    #pragma once
    
    #define WIN32_LEAN_AND_MEAN                     // Exclude rarely used material from Windows headers.
    
    #include <stdio.h>
    
    #include <tchar.h>
    
    #include <windows.h>
    
    #include <wincrypt.h>
    
  6. 在 [專案] 功能表上按一下 [屬性] 開啟此專案的屬性頁]。
  7. 展開 [連結器] 節點,然後按一下 [輸入
  8. 在右邊的 [其他相依性,空白的視窗中按一下,然後按一下省略符號按鈕 (...) 以開啟 [其他相依性] 對話方塊。
  9. 空白視窗中輸入 Crypt32.lib,],然後再按一下 [確定]]。
  10. 按一下 [套用],然後再按一下 [確定] 以關閉屬性頁。
  11. 在 [建置] 功能表上按一下 [建置方案]。
  12. 建置方案之後執行下列命令以更新憑證:
    renewcert <OldCertificate>.pfx <NewCertificate>.pfx \"CN=<NewCertificateName>\" <Password>
    注意 <OldCertificate> 是舊的憑證預留位置 <NewCertificate> 是新的憑證預留位置 <NewCertificateName> 是新的憑證和 <Password> 是密碼的預留位置。

其他相關資訊

如果要重現這個問題的步驟

  1. 啟動 Visual Studio 2005。
  2. 檔案 上按一下 [新增],] 然後按一下 [專案] 功能表。
  3. 按一下 [Visual C# 按一下 [Windows 應用程式、 在 [名稱] 方塊中鍵入 WindowsApplication1 然後再按一下 [確定]
  4. 在 [方案總管] 中 WindowsApplication1,] 上按一下滑鼠右鍵,然後按一下 [內容]。
  5. 按一下 [簽章,然後再分派很快就過期的憑證。
  6. 在 [方案總管] 中 WindowsApplication1,] 上按一下滑鼠右鍵,然後按一下 [發佈]。[發佈] 精靈隨即啟動。
  7. Where 是否要將應用程式發行至? 頁面、 輸入有效的 URL,然後按一下 [下一步]。使用下列格式的 URL:
    http:// ServerName / FolderName
  8. 是否可以在離線時使用應用程式?? 頁面上,按一下適當的選項。

    備忘稿
    • 如果您想讓使用者中斷網路連線時,執行應用程式的使用者,按一下 [[是],這個應用程式將可線上或離線。精靈會在 [開始] 功能表上建立應用程式的捷徑。
    • 如果您想從發行位置直接執行應用程式,按一下 [否],這個應用程式只線上時使用。精靈不會在 [開始] 功能表上建立捷徑。
  9. 按 [下一步] 以繼續。
  10. 按一下 [完成] 發行應用程式]。
  11. 從 http:// ServerName 安裝 ClickOnce 應用程式 / FolderName /publish.htm URL。
  12. 憑證過期後重複步驟 6 到 10 若要重新發佈應用程式。
  13. 嘗試安裝 ClickOnce 應用程式更新從 http:// ServerName / FolderName /publish.htm URL。

屬性

文章編號: 925521 - 上次校閱: 2009年3月12日 - 版次: 4.1
這篇文章中的資訊適用於:
  • Microsoft Visual Studio 2005 Standard Edition
  • Microsoft Visual Studio 2005 Professional Edition
  • Microsoft Visual Studio 2005 Express Edition
關鍵字:?
kbmt kbtshoot kberrmsg kbbug kbprb KB925521 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:925521
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com