从头开始部署时如何获取App_Data
@tdykstra已经正确处理了。为了将App_Data部署到服务器上(并自动设置ACLs),我执行了以下操作:
- 在App_Data中添加一个占位符文件。
- 将占位符的生成操作设置为内容(我的占位符文件中有文字,让那些偶然发现它的人知道它存在的原因)。
- 取消选中“在VS 2010项目属性的Package/Publish Web选项卡中排除App_Data文件夹中的文件”。
这样就可以创建并准备好我的App_Data文件夹以在服务器上使用。但是,每次重新发布时都会导致所有文件被删除。这是我上面提到的问题#2,并且与此其他SO question/answer非常相似。
防止服务器上的数据在后续发布事件中被删除
MsDeploy有两种机制可能会混淆(至少我混淆了):
- 排除文件
- MsDeploy跳过规则
这两者都可以用来解决问题,具体取决于情况:
- @tdykstra的解决方案可能适用于您:
- 预先知道App_Data中文件的名称(例如sqllite数据库)
- 在项目中包含了App_Data文件夹中的文件
- 使用MsDeploy跳过规则告诉MsDeploy完全跳过该目录和该目录中的文件上的所有删除操作。 这解决了所有情况下的问题,但涉及更多步骤。
实施MsDeploy跳过规则
要实施跳过规则,您将不得不放弃VS 2010中的右键“部署”选项,改为右键“打包”,进入命令行,重新调整批处理文件并运行命令行)。 如果您愿意忍受这种体验(我愿意,因为我通过CI流程自动化了所有内容),以下是详细信息:
Edit the project file and add the following. Note that the AbsolutePath argument is a regular expression, so you can get way fancy:
<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>
- Package, do not deploy the project. This will create a zip file and .cmd file in the target directory (defined by "Location where package will be created" on the Package/Publish Web Tab). By default, this is obj\Debug\Package (or obj\Release\Package)
- Deploy the site using the the resulting command file
在我的测试中,您必须打包并运行命令文件。项目文件中的调整将告诉msbuild将必要的-skip规则放入命令文件中。但是,直接使用VS 2010中的“发布”功能似乎
不会运行命令文件(请参见
此演练上的警告)……它直接调用msdeploy,并且似乎不尊重项目文件的跳过规则。我认为这就是VS使用msbuild -T:Package和msbuild -T:MsDeployPublish构建项目之间的区别,但我还没有测试过。
最后,命令文件并不完全正确,至少在VS 2010 SP1中如此。这里有一个
SO答案很好地描述了出了什么问题,但基本上,VS(或者可能/t:Package目标更为罪魁祸首)设置了发布到机器的命令文件而没有指定站点。为了解决这个问题,您需要以某种方式将"? site=
sitename"(可能是? site=Default+Web+Site,对于https://
machine:8172/MsDeploy.axd?site=Default+Web+Site的完整URL)附加到computerName参数的末尾。
我的问题是命令文件(批处理文件)在使用命令行时使用站点=任何内容都会出现问题,因为它错误地解析了命令行参数(即使转义)。我看不到除修改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选项),它将按预期工作。
<UseMSDeployExe>true</UseMSDeployExe>
,否则在使用VS2017和MsDeploySkipRules
时其实并不起作用。 - ceztko