如何从 makefile 打包 WCF 服务...?
我在 Visual Studio 中有一个 WCF 项目,需要将其部署到客户端的测试服务器。当我即将宣布“任务完成”时,我意识到我不知道如何将我的项目从 Visual Studio 2010 转移到可以部署在客户端服务器上的项目。
我的这个问题的要点是,我们在部署到客户端时使用 makefile 来进行构建和打包。这意味着我需要一个命令行可执行文件来执行部署 WCF 服务所需的任何操作。我确实发现右键单击该项目并选择“构建部署包”,但由于我需要通过命令行执行,所以我认为这不会有太大帮助。
这个问题的第二部分是,一旦我从客户端服务器获得打包文件,我不知道如何处理它。现在,如果我知道打包的部署文件会发生什么,我可能会有更好的想法,但在那之前,这一切都只是猜测。
I have a WCF project in Visual Studio that I need to deploy to a client's test server. I was on the brink of declaring "Mission Accomplished" when I realized that I have no idea how to take my project from Visual Studio 2010 to something that I can deploy on the client's server.
My gist of this problem is that we use a makefile to do building and packaging when deploying to the client. This means that I need a command-line executable to do whatever it is that I need to do to deploy my WCF service. I did discover right-clicking the project and selecting "Build Deployment Package", but since I need to execute via command-line, I don't think this is going to help much.
The bonus second part of this problem is that, once I get the packaged file the client's server, I'm not sure what to do with it. Now, if I knew what to expect from the packaged deployment file, I might have a better idea, but until then, it's all just speculation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,这就是我的想法。
包装
首先,包装。使用 msbuild.像这样的东西(显然你需要使用 v4 或更好版本的 .NET 才能成功):
C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe {project_file} /t:package /target:Build /p:PlatformTarget=x86;
相当容易,对吧?
部署
现在,问题的奖励部分是部署。这由简单部分和困难部分组成。最简单的部分是将使用 msbuild.exe 创建的 .zip 文件添加到 IIS 中。我发现了2种可能性。
命令行
第一个是命令行,它给我带来了问题(关于无法将“Microsoft.Web.Deployment.DeploymentProviderOptions”强制转换为“Microsoft.Web.Deployment.DeploymentProviderOptions<”) /strong>' --- 我知道,对吧?)。无论如何,这是我使用的命令行。它可能对某人有帮助,也可能没有帮助。我再次遇到了问题。
c:\inetpub\wwwroot>"c:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -presync:runCommand="md c:\inetpub\wwwroot\{MyWCFCodeDest} & c:\windows\system32\inetsrv\appcmd 添加站点 /name:{MyWCFCodeDest} /id:22绑定:http/*:54095: /physicalPath:c:\inetpub\wwwroot\{MyWCFCodeDest}" -source:package={ZipFileFromMSBuild.exe} -dest:auto -setParam:"IIS Web 应用程序名称"="{MyIISName} “
UI
好的,所以我决定我会很乐意使用第二种方式。如果您不关心自动化,这是迄今为止最简单的。打开 IIS 管理器,右键单击计算机或网站(取决于您是否希望将其作为自己的网站或现有网站中的应用程序)、部署、导入,然后按照向导完成操作。
部署中的错误
现在我花了大部分时间。我点击新部署的 .svc 文件并收到错误。此错误涉及我正在使用的证书。现在,也许并非所有部署都需要担心这个问题,但我的部署却需要担心。错误很长,有关“密钥集不存在”和“由于编译期间出现异常而无法激活”和“可能没有私钥能够进行密钥交换,或者该进程可能没有私钥的访问权限”。我尝试了很多东西,包括使用 mmc 重新导入证书和 makecert 重新创建我的 CA 和个人证书。这些对我来说都不是问题(ymmv)。最后,我重点关注用户权利。我发现,如果我向“每个人”用户授予证书私钥的权限(证书需要有私钥),则一切正常。显然这不是我想要为客户提供的解决方案,因此我找到了正确的用户来授予权限。令人惊讶的是,这花了一段时间。各种网站让我添加网络服务、ASPNET、当前用户、machine.config 中指定的用户(位于 .NET 目录中的某个位置)、IIS_{MachineName}...这些都不起作用。我必须添加的是 IIS_IUSRS。
因此,当您对着显示器尖叫,尽管遵循了所有指示,但这对您不起作用时,一些警告可能会帮助您保持理智。因为显然 IIS 随着时间的推移发生了太多变化,而这些东西确实很重要:
Windows 7 Ultimate sp1
IIS 7.5.7600.16385
有用的相关内容
此外,您可能会对一些命令行工具感兴趣:
-winhttpcertcfg.exe -l -c LOCAL_MACHINE\My -s "{cert_name}" -- 列出有权访问证书私钥的用户(您也可以通过文件属性以老式方式执行此操作) );我尝试下载 winhttpcertcfg.exe,但它是 Windows 2003 软件包的一部分,会发出有关不兼容的警告(不确定它是否来自我尝试安装该文件,或者它现在是否附带了我已经安装的东西)
-winhttpcertcfg.exe -g -c LOCALHOST\My -s "{cert_name}" -a IIS_IUSRS -- 将 IIS_IUSRS 添加到证书私钥的权限
-findprivatekey.exe My LocalMachine -n "{cert_name}" -- 查找指定证书的私钥文件;由于某种原因,这是一个您必须在 Dev Studio 中自行构建的工具(可以在从 Microsoft 下载的一些 WCF 示例中找到)
-cacls.exe {private_key_file_for_cert} /E /G "IIS_IUSRS" -- 将用户添加到私钥权限的另一种方法
-mmc -- 启动已安装证书的管理器
-makecert -n "CN={CertificateAuthorityName}" -r -sv {CertificateAuthorityName}.pvk {CertificateAuthorityName}.cer -- 创建证书颁发机构证书
-makecert -sk {SignedCertName} -iv {CertificateAuthorityName}.pvk -n "CN={SignedCertName}" -ic {CertificateAuthorityName}.cer {SignedCertName}.cer -sr localmachine -ss My --创建由证书颁发机构签名的证书
最后一件事:如果要使用 mmc 导入证书,则需要启动 mmc,文件->添加/删除管理单元。添加证书管理单元。将证书颁发机构导入“受信任的根证书颁发机构”,并将证书颁发机构签名的证书导入“个人”。
希望您在这里度过愉快的旅程。请等待浏览器完全停止后再退出,并请记得随身携带任何个人物品。
其他发现
当需要将所有内容部署到测试服务器(而不是我的开发计算机)时,我没想到会遇到所有麻烦。我再次在这里记录这些,是为了帮助其他一些可怜的、迷失的灵魂(或者以后的我自己)。
-这一点应该很明显:FindPrivateKey.exe 不在服务器上。我必须克服一些困难才能到达那里。 ymmv。
- 服务器上仅安装了.NET 客户端4.0 版本。当我发现这一点并意识到这是一个问题时,已经过去了几个小时。已安装的 .NET 版本的发现是由我从 Microsoft 网站之一获得的 netfx_setupverifier 提供的。客户端版本不包含所有 WCF 内容。
-IIS 需要一些额外的设置(在 .NET Framework 版本目录中找到的文件,从命令行运行):
aspnet_regiis.exe -i -enable
ServiceModelReg.exe -r
-cacls.exe 通知我它已被弃用,我应该使用icacls.exe。 icacls 的命令行类似于:
icacls.exe {private_key_file_for_cert} /GRANT "IIS_IUSRS":R
(注意,这对我来说并不完全有效,但您始终可以转到 {private_key_file_for_cert} 文件,可能位于 ProgramData\Microsoft\ Crypto\RSA\MachineKeys,并通过资源管理器授予权限 - 右键单击 - 属性)-您可能需要为 WCF 添加处理程序映射。我强烈建议让它在 .NET v4.0 应用程序池下运行。
OK, here is what I came up with.
Packaging
First, the packaging. Use msbuild. Something like this (apparently you need to use a v4 or better version of .NET for it to succeed):
C:/Windows/Microsoft.NET/Framework/v4.0.30319/msbuild.exe {project_file} /t:package /target:Build /p:PlatformTarget=x86;
Fairly easy, right?
Deployment
Now, the bonus part of the question, the deployment. This consists of the easy part and the hard part. The easy part was getting the .zip file created with msbuild.exe added into IIS. I found 2 possibilities.
Commandline
The first is the command-line, which gave me issues (something about being unable to cast 'Microsoft.Web.Deployment.DeploymentProviderOptions' to type 'Microsoft.Web.Deployment.DeploymentProviderOptions' --- I KNOW, RIGHT?). Anyway, this is the command-line I used. It may help someone, or it may not. Again, I had issues with it.
c:\inetpub\wwwroot>"c:\Program Files\IIS\Microsoft Web Deploy\msdeploy.exe" -verb:sync -presync:runCommand="md c:\inetpub\wwwroot\{MyWCFCodeDest} & c:\windows\system32\inetsrv\appcmd add site /name:{MyWCFCodeDest} /id:22 bindings:http/*:54095: /physicalPath:c:\inetpub\wwwroot\{MyWCFCodeDest}" -source:package={ZipFileFromMSBuild.exe} -dest:auto -setParam:"IIS Web Application Name"="{MyIISName}"
UI
OK, so I decided I would be happy with using the second way. It's by far the easiest if you don't care about automation. Open up IIS Manager, right-click the computer OR the website (depending on whether you want it as its own website or an application in an existing website), Deploy, Import, and follow the wizard to the end.
Errors in Deployment
And now where I spent most of my time. I hit my newly deployed .svc file and get an error. This error involves the certificate I was using. Now, maybe not all deployments will have to worry about this, but mine did. The error was lengthy, something about "keyset does not exist" and "cannot be activated due to an exception during compilation" and "may not have a private key that is capable of key exchange or the process may not have access rights for the private key". I tried a bunch of stuff, including using mmc to re-import certs and makecert to recreate both my CA and my personal cert. None of that was the problem for me (ymmv). Finally, I focused on user rights. I found that if I gave the Everyone user permission to the private key for the cert (the cert needs to have a private key), everything worked. Obviously not a solution I want for a client, so I hunted down the correct user to give rights to. Surprisingly, this took a while. Various websites had me adding Network Service, ASPNET, current user, the user specified in machine.config (which is in the .NET directory somewhere), IIS_{MachineName}... none of these worked. The one I had to add was IIS_IUSRS.
So, a handful of caviats that may help your sanity when you scream at your monitor that this isn't working for you, despite following all the directions. Because apparently IIS changes far too much over time and this stuff does matter:
Windows 7 Ultimate sp1
IIS 7.5.7600.16385
Useful Related Stuff
Also, some commandline tools you may be interested in:
-winhttpcertcfg.exe -l -c LOCAL_MACHINE\My -s "{cert_name}" -- lists the users authorized to access the cert's private key (you can also do it the old fashioned way through file properties); I tried downloading winhttpcertcfg.exe, but it was part of a Windows 2003 package that gives warnings about not being compatible (not sure if it came from my attempt to install that file or if it now comes with something I already had installed)
-winhttpcertcfg.exe -g -c LOCALHOST\My -s "{cert_name}" -a IIS_IUSRS -- adds IIS_IUSRS to the permissions for the cert's private key
-findprivatekey.exe My LocalMachine -n "{cert_name}" -- Finds the private key file for the specified cert; for some reason, this is a tool that you have to build in Dev Studio on your own (found in some WCF examples downloaded from Microsoft)
-cacls.exe {private_key_file_for_cert} /E /G "IIS_IUSRS" -- another way to add a user to the private key's permissions
-mmc -- launchs a manager for installed certificate
-makecert -n "CN={CertificateAuthorityName}" -r -sv {CertificateAuthorityName}.pvk {CertificateAuthorityName}.cer -- create a certificate authority cert
-makecert -sk {SignedCertName} -iv {CertificateAuthorityName}.pvk -n "CN={SignedCertName}" -ic {CertificateAuthorityName}.cer {SignedCertName}.cer -sr localmachine -ss My -- create a certificate signed by a certificate authority
One last thing: if you want to import your certs using mmc, you need to launch mmc, File->Add/Remove Snapin. Add the Certificates snapin. Import the certificate authority to the Trusted Root Certification Authorities and the certificate signed by the certificate authority to Personal.
Hopefully you have enjoyed your ride here. Please wait for the browser to come to a complete stop before exiting, and please remember to take any personal items with you.
Additional Discoveries
When it came time to deploy everything to a test server (rather than my development machine), I didn't expect all the hassles that I encountered. I'm documenting these here, again, in an effort to help some other poor, lost soul (or myself at a later date).
-This one should have bee obvious: FindPrivateKey.exe wasn't on the server. I had to jump through some hoops to get it there. ymmv.
-Only the client 4.0 version of .NET had been installed on the server. By the time I discovered this AND realized it was a problem, a few hours had passed. Discovery of the installed .NET versions came courtesy of netfx_setupverifier, which I got from one of Microsoft's websites. The client version doesn't include all the WCF stuff.
-IIS needed some additional settings (files found in the .NET Framework version directory, run from the commandline):
aspnet_regiis.exe -i -enable
ServiceModelReg.exe -r
-cacls.exe informed me that it was deprecated and that I should use icacls.exe. The commandline for icacls is something like:
icacls.exe {private_key_file_for_cert} /GRANT "IIS_IUSRS":R
(note, didn't exactly work for me, but you can always just go to the {private_key_file_for_cert} file, probably in ProgramData\Microsoft\Crypto\RSA\MachineKeys, and give permissions via Explorer - right-click - properties)-You may need to add a handler mapping for the WCF. I highly recommend having it running under an Application Pool that is .NET v4.0.