我如何获得msdeploy创建的App_Data,如果它不存在,但不能删除远程目录中的任何内容?它不、如何获得、存在、内容

2023-09-02 01:46:45 作者:穿着拖鞋走天下

我有一个应用程序安装具有以下封装/发布站点设置:

只有文件需要运行该应用程序 (未选中)排除生成的调试符号 (检查),排除在App_Data文件夹中的文件 (检查)包括配置在包中的所有数据库/发布SQL选项卡 - 请注意我做的没有的已配置的任何数据库 (未选中)包括IIS设置在IIS中配置防爆preSS

在项目中,我有一个App_Data文件夹的设置,主要是为了处理应用程序日志。

我希望看到(和期望)的行为如下:

在初始部署到全新的服务器,应用程序将被复制和App_Data文件夹与分配给应用程序写入权限创建。 在随后的部署,App_Data文件夹被忽略,因为它已经存在与排除在App_Data文件夹中的文件被选中。

然而,msdeploy不会出现做步骤#1(步骤2是好的,如果我手动创建的文件夹)。我一直无法找到网络上的任何文件,除此之外unanswered这样的问题这似乎证实了我看到的行为。

我要如何msdeploy创建的App_Data,在这种情况下分配的初始部署的权限?

解决方案

获取从头开始时的App_Data部署

@tdykstra得到这部分权。要获得的App_Data有(自动设置ACL),我做了以下内容:

在App_Data文件添加一个占位符文件 设置生成操作到内容上的占位符(我的占位符文件中有文字,让人们通过它绊倒知道为什么它的存在)。 未检查的包排除在App_Data文件夹中的文件/发布在VS 2010中项目属性的网页标签

这得到我的App_Data文件夹中创建并准备在服务器上使用。然而,这将导致每当我重新发布我的所有文件越来越删除。这是问题的#2,我的问题上面,和pretty的近似于这另一个SO question/答案。

被删除,在随后的事件发布在服务器上的preventing数据

哔哩哔哩B站商业起飞计划怎么做 0基础 保姆级投放推广策略

有在MsDeploy两种机制,可以感到困惑(至少我却把它们):

排除文件 MsDeploy跳过规则

这些都可以用来解决该问题,根据方案:

@ tdykstra的解决方案可能会,如果你的工作: 知道的App_Data文件提前的名称(如sqllite数据库) 包含在App_Data文件夹有文件可以在您的项目 在使用MsDeploy跳过规则告诉MsDeploy完全跳过服务器的目录和文件在该目录中的所有删除。这解决了在所有情况下的问题,但更复杂。

实施MsDeploy跳过规则

要实现跳跃规则,你必须有利于用鼠标右键单击,包抛弃在VS 2010中右击,部署选项,进入命令行,重跳汰机的批处理文件,然后运行命令行) 。如果你愿意忍受这样的经历(我,因为我自动化这一切通过一个CI过程),下面是详细信息:

编辑项目文件并添加以下。需要注意的是AbsolutePath参数是一个常规的前pression,这样你就可以得到这样奇特的:

 <目标名称=AddCustomSkipRules>
    < ItemGroup>
      < MsDeploySkipRules包括=SkipDeleteAppData>
        < SkipAction>删除< / SkipAction>
        <的ObjectName>文件路径< /的ObjectName>
        < AbsolutePath> $(_ Escaped_PackageTempDir)\ \的App_Data *< / AbsolutePath>
        < XPath的>
        < / XPath的>
      < / MsDeploySkipRules>
      < MsDeploySkipRules包括=SkipDeleteAppData>
        < SkipAction>删除< / SkipAction>
        <的ObjectName> dirPath< /的ObjectName>
        < AbsolutePath> $(_ Escaped_PackageTempDir)\ \的App_Data *< / AbsolutePath>
        < XPath的>
        < / XPath的>
      < / MsDeploySkipRules>
    < / ItemGroup>
< /目标>
 

包装,不部署的项目。这将创建在目标目录中的zip文件,.cmd文件(里包将被创建的位置上的包被定义/发布Web选项卡)。默认情况下,这是OBJ 调试包(或OBJ 发布包) 利用部署站点的产生的命令文件

在我的测试中,你必须打包并运行命令文件。项目文件的调整会告诉的MSBuild建立必要的-skip规则到命令文件。但是,使用发布功能,直接从VS 2010 似乎并没有运行命令文件(见警告此演练)......它直接调用msdeploy和似乎并不荣誉的项目文件跳过规则。我相信这是一个使用的MSBuild -T VS之间的区别:包和的MSBuild -T:MsDeployPublish建项目,但我没有测试过这一点。

最后,该命令文件是不太正确的,至少在VS 2010 SP1。有什么不顺心这太回答一个伟大的描述,但基本上,VS(或者也许是/ T:包装目标是一个更好的罪魁祸首)设置的命令文件发布到本机,而无需指定的站点。为了解决这个问题,你需要以某种方式获得(可能这是网站=默认+网络+现场,对HTTPS的完整URL的网站= 站点名称的?:// 机的:?8172 / MsDeploy.axd网站=默认值+网络+网站)到计算机名参数的结尾。

我的问题是,该命令文件(批处理文件),也很难利用网站=命令行上的任何内容,因为它错误地分析命令行参数(即使逃脱)。我没有看到解决这个问题,而不是直接修改CMD文件以外的方式,但对于测试我复制了msdeploy.exe输出从我失败的测试运行所看到和修改,为msdeploy.exe直接调用,而无需脚本。

现在,它的工作,我的意思是这样的工作进入我的CI构建过程。我会做的最后的解决方案是:

更改我的生成脚本,以使用/ T:包装(现在它/ T:MsDeploy) 有一个脚本查找/替换常规的改变所产生的CMD部署脚本 运行改变部署脚本

这真的应该更容易。

更新

这里的脚本查找/替换程序,我拿出在PowerShell中:

 (获取内容project.deploy.cmd)
  -replace('^套_ArgComputerName = $'
           设置ArgComputerName = https://开头的服务器:8172 / MsDeploy.axd网站=默认值+网络+网站)
  |出文件-encoding ASCII deploy.cmd
 

一旦运行,deploy.cmd可以被称为(不带/ M选项),它会正常工作。

I have an application setup with the following Package/Publish Web settings:

Only files needed to run this application (unchecked) Exclude generated debug symbols (checked) Exclude files from the App_Data folder (checked) Include all databases configured in Package/Publish SQL tab - note I do not have any databases configured (unchecked) include IIS settings as configured in IIS Express

In the project, I have an App_Data folder setup, primarily to handle application logs.

The behavior I'd like to see (and expect) is the following:

On initial deploy to a brand new server, the application is copied and an App_Data folder is created with write permissions assigned for the application. On subsequent deployments, the App_Data folder is ignored because it already exists and the "Exclude files from the App_Data folder" is checked.

However, msdeploy does not appear to do step #1 (step 2 is fine if I create the folder manually). I've been unable to find any documentation on the web besides this unanswered so question that seems to confirm the behavior I see.

How do I get msdeploy to create App_Data and assign permissions on initial deployment in this scenario?

解决方案

Getting App_Data deployed when starting from scratch

@tdykstra got this part right. To get App_Data out there (and ACLs set automatically), I did the following:

Adding a placeholder file in App_Data Set the build action to content on the placeholder (my placeholder file has text in it to let people stumbling across it know why it's there). Unchecked "Exclude files from the App_Data folder" on the Package/Publish Web tab of the project properties in VS 2010

This gets my App_Data folder created and ready for use on the server. However, it will result in all my files getting deleted whenever I republish. This is problem #2 in my question above, and pretty closely resembles this other SO question/answer.

Preventing data on the server from being deleted on subsequent publish events

There are two mechanisms in MsDeploy that can get confused (at least I confused them):

Excluding files MsDeploy skip rules

These can both be used to solve the problem, depending on the scenario:

@tdykstra's solution will likely work if you:

Know the names of the files in App_Data in advance (e.g. a sqllite database) Have the files included in the App_Data folder in your project

The use MsDeploy skip rules to tell MsDeploy to completely skip all deletes on the server for that directory and files in that directory. This solves the problem in all cases, but is much more involved.

Implementing MsDeploy skip rules

To implement skip rules you'll have to abandon the right-click, Deploy option in VS 2010 in favor of right-click, Package, go into a command line, re-jigger a batch file and run a command line). If you're willing to put up with this experience (I am, because I'm automating it all through a CI process), here are the details:

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 objDebugPackage (or objReleasePackage) Deploy the site using the the resulting command file

In my testing, you must package and run the command file. The project file tweaks will tell msbuild to put the necessary -skip rule into the command file. However, using the "publish" feature straight from VS 2010 doesn't seem to run the command file (see the warning on this walkthrough)...it calls msdeploy directly and doesn't seem to honor the project file skip rules. I believe this is the difference between VS using msbuild -T:Package and msbuild -T:MsDeployPublish to build the project, but I have not tested this.

Finally, the command file isn't quite correct, at least in VS 2010 SP1. There's a great description of what goes wrong in this SO answer, but basically, VS (or maybe the /t:Package target is a better culprit) sets up the command file to publish to the machine without specifying a site. To fix that, you'll need to somehow get "?site=sitename" (probably this is ?site=Default+Web+Site, for a full URL of https://machine:8172/MsDeploy.axd?site=Default+Web+Site) onto the end of the computerName argument.

The problem I had was that the command file (batch file) has a hard time with using site= anything on the command line since it mis-parses the command line argument (even if escaped). I don't see a way around this problem other than modifying the cmd file directly, but for testing I copied the msdeploy.exe output I saw from my failed test run and modified that to call msdeploy.exe directly without the script.

Now that it's working, my intention is to work this into my CI build processes. What I'll be doing for the final solution is:

Change my build script to use /T:Package (right now it's /T:MsDeploy) Have a scripted search/replace routine alter the generated cmd deployment script Run the altered deployment script

This really should be easier.

Update

Here's the scripted search/replace routine I've come up with in 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

Once that is run, deploy.cmd can be called (without the /M option) and it will work as expected.