当您尝试更新 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. 在可视有关 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. 在该 您要在哪里发布该应用程序? 页上,键入一个有效的 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
  • Microsoft Visual Studio 2005 Express Edition
关键字:?
kbmt kbtshoot kberrmsg kbbug kbprb KB925521 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 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