从头开始部署 App_Data
@tdykstra 得到了this part right。为了获取 App_Data(并自动设置 ACL),我执行了以下操作:
- 在 App_Data 中添加占位符文件
- 将构建操作设置为占位符上的内容(我的占位符文件中有文本,让偶然发现它的人知道它为什么存在)。
-
未选中“从 App_Data 文件夹中排除文件”在 VS 2010 中项目属性的“打包/发布 Web”选项卡上
这将创建我的 App_Data 文件夹并准备好在服务器上使用。但是,每当我重新发布时,它都会导致我的所有文件都被删除。这是我上面的问题中的问题 #2,与其他 SO question/answer 非常相似。
防止服务器上的数据在后续发布事件中被删除
MsDeploy 中有两种机制会让人感到困惑(至少我把它们弄糊涂了):
- 排除文件
- MsDeploy 跳过规则
这些都可以用来解决问题,具体取决于场景:
-
如果您满足以下条件,@tdykstra's solution 可能会起作用:
- 提前知道 App_Data 中文件的名称(例如 sqllite 数据库)
- 将文件包含在项目的 App_Data 文件夹中
- 使用 MsDeploy 跳过规则告诉 MsDeploy 完全跳过服务器上对该目录和该目录中的文件的所有删除。这解决了所有情况下的问题,但涉及更多。
实施 MsDeploy 跳过规则
要实现跳过规则,您必须放弃 VS 2010 中的右键单击、部署选项,转而支持右键单击、打包、进入命令行、重新启动批处理文件并运行命令行) .如果您愿意忍受这种体验(我愿意,因为我通过 CI 流程将其全部自动化),以下是详细信息:
-
Edit the project file and add the following。请注意,AbsolutePath 参数是一个正则表达式,所以你可以很花哨:
<Target Name="AddCustomSkipRules">
<ItemGroup>
<MsDeploySkipRules Include="SkipDeleteAppData">
<SkipAction>Delete</SkipAction>
<ObjectName>filePath</ObjectName>
<AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
<MsDeploySkipRules Include="SkipDeleteAppData">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>$(_Escaped_PackageTempDir)\\App_Data\\.*</AbsolutePath>
<XPath>
</XPath>
</MsDeploySkipRules>
</ItemGroup>
</Target>
- 打包,不要部署项目。这将在目标目录中创建一个 zip 文件和 .cmd 文件(由 Package/Publish Web 选项卡上的“创建包的位置”定义)。默认情况下,这是 obj\Debug\Package(或 obj\Release\Package)
- 使用生成的命令文件部署站点
在我的测试中,你必须打包并运行命令文件。项目文件调整将告诉 msbuild 将必要的 -skip 规则放入命令文件中。但是,直接从 VS 2010 doesn't seem to run the command file 使用“发布”功能(请参阅 this walkthrough 上的警告)...它直接调用 msdeploy 并且似乎不遵守项目文件跳过规则。我相信这是 VS 使用 msbuild -T:Package 和 msbuild -T:MsDeployPublish 构建项目的区别,但我没有对此进行测试。
最后,命令文件不太正确,至少在 VS 2010 SP1 中是这样。 this SO answer 中有一个很好的错误描述,但基本上,VS(或者 /t:Package 目标是一个更好的罪魁祸首)设置命令文件以发布到机器而不指定站点。要解决这个问题,您需要以某种方式获取“?site=sitename”(可能是 ?site=Default+Web+Site,对于 https://machine 的完整 URL :8172/MsDeploy.axd?site=Default+Web+Site) 到 computerName 参数的末尾。
我遇到的问题是命令文件(批处理文件)很难在命令行上使用 site= any,因为它错误地解析了命令行参数(即使转义)。除了直接修改 cmd 文件之外,我没有看到解决此问题的方法,但为了测试,我复制了我从失败的测试运行中看到的 msdeploy.exe 输出,并将其修改为在没有脚本的情况下直接调用 msdeploy.exe。
现在它可以工作了,我打算将它应用到我的 CI 构建过程中。我将为最终解决方案做的是:
- 将我的构建脚本更改为使用 /T:Package(现在是 /T:MsDeploy)
- 让脚本搜索/替换例程更改生成的 cmd 部署脚本
- 运行修改后的部署脚本
这真的应该更容易。
更新
这是我在 PowerShell 中提出的脚本搜索/替换例程:
(Get-Content "project.deploy.cmd")
-replace('^set _ArgComputerName=$'
,"set ArgComputerName=https://server:8172/MsDeploy.axd?Site=Default+Web+Site")
| Out-File -Encoding ascii deploy.cmd
运行后,可以调用 deploy.cmd(不带 /M 选项),它将按预期工作。