10

I have:

  1. Created a manifest for msdeploy to:
    Stop, Uninstall, Copy over, Install, and Start a Windows service.
  2. Created a package from the manifest
  3. Executed msdeploy against the package against a remote server.

Problem: It executes the entire manifest twice.

Tried: I have tinkered with the waitInterval and waitAttempts thinking it was timing out and starting over, but that hasn't helper.

Question: What might be making it execute twice?

The Manifest:

<sitemanifest>
  <runCommand path="net stop TestSvc"
              waitInterval="240000"
              waitAttempts="1"/>

  <runCommand 
    path="C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u
       C:\msdeploy\TestSvc\TestSvc\bin\Debug\TestSvc.exe"
       waitInterval="240000"
       waitAttempts="1"/>

  <dirPath path="C:\msdeploy\TestSvc\TestSvc\bin\Debug" />

  <runCommand 
    path="C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe
    C:\msdeploy\TestSvc\TestSvc\bin\Debug\TestSvc.exe"
    waitInterval="240000"
    waitAttempts="1"/>

  <runCommand path="net start TestSvc"
    waitInterval="240000"
    waitAttempts="1"/>

</sitemanifest>

The command issued to package it:

"C:\Program Files\IIS\Microsoft Web Deploy V2\msdeploy" 
         -verb:sync 
         -source:manifest=c:\msdeploy\custom.xml 
         -dest:package=c:\msdeploy\package.zip

The command issued to execute it:

"C:\Program Files\IIS\Microsoft Web Deploy V2\msdeploy" 
         -verb:sync 
         -source:package=c:\msdeploy\package.zip 
         -dest:auto,computername=<computerNameHere>

I am running as a domain user who has administrative access on the box. I have also tried passing credentials - it is not a permissions issue, the commands are succeeding, just executing twice.


Edit:

I enabled -verbose and found some interesting lines in the log:

Verbose: Performing synchronization pass #1.

...

Verbose: Source filePath (C:\msdeploy\MyTestWindowsService\MyTestWindowsService\bin\Debug\MyTestWindowsService.exe) does not match destination (C:\msdeploy\MyTestWindowsService\MyTestWindowsService\bin\Debug\MyTestWindowsService.exe) differing in attributes (lastWriteTime['11/08/2011 23:40:30','11/08/2011 23:39:52']). Update pending.

Verbose: Source filePath (C:\msdeploy\MyTestWindowsService\MyTestWindowsService\bin\Debug\MyTestWindowsService.pdb) does not match destination (C:\msdeploy\MyTestWindowsService\MyTestWindowsService\bin\Debug\MyTestWindowsService.pdb) differing in attributes (lastWriteTime['11/08/2011 23:40:30','11/08/2011 23:39:52']). Update pending.

After these lines, files aren't copied the first time, but are copied the second time

...

Verbose: The dependency check 'DependencyCheckInUse' found no issues.
Verbose: Received response from agent (HTTP status 'OK').
Verbose: The current synchronization pass is missing stream content for 2 objects.

Verbose: Performing synchronization pass #2.

...


High Level

Normally I deploy a freshly built package with newer bits than are on the server.

During pass two, it duplicates everything that was done in pass one.

In pass 1, it will:

  • Stop, Uninstall, (delete some log files created by the service install), Install, and Start a Windows service

In pass 2, it will:

  • Stop, Uninstall, Copy files over, Install, and Start a Windows service.

I have no idea why it doesn't copy over the files in pass 1, or why pass 2 is triggered.

If I redeploy the same package instead of deploying fresh bits, it will run all the steps in pass 1, and not run pass 2. Probably because the files have the same time stamp.

SteveC
  • 15,808
  • 23
  • 102
  • 173
Tim Bassett
  • 101
  • 4

2 Answers2

1

There is not enough information in the question to really reproduce the problem to give a specific answer... but there are several things to check/change/try to make this work:

EDIT - after the addition of -verboseoutput:

I see these possibilities:

  • Time
    Both machines have a difference in time (either one of them is just a bit off or some timezone issue...)
  • Filesystem
    If one of the filesystems is FAT this could lead to problems (timestamp resolution...)

EDIT 2 - as per comments:

In my last EDIT I wrote about timestamp because my suspicion is that something goes wrong when these are compared... that can be for example differring clocks between both machines (even a difference of 30 sec can have an impact) and/or some timezone issues...

I wrote about filesystem esp. FAT since the timestamp resolution of FAT is someabout 2 seconds while NTFS has much higher resolution, again this could have an impact when comparing timestamps...

From what you describe I would suggest the following workarounds:

EDIT 3 - as per comment from Merlyn Morgan-Graham the result for future reference:

When using the runCommand provider, use batch files. For some reason this made it stop running two passes.

The problem with this solution is that one can't specify the installation directory of the service via a SetParameters.xml file (same for dontUseCommandExe / preSync / postSync regarding SetParameters.xml).

EDIT 4 - as per comment from Merlyn Morgan-Graham:

The timeout params apply to whether to kill that specific command, not to the closing of the Windows Service itself... in this case it seems that the Windows Service takes rather long to stop and thus only the runCommands get executed without the copy/sync and a new try for the whole run is initiated...

Yahia
  • 69,653
  • 9
  • 115
  • 144
  • The commands aren't failing either time, so I am not sure it is a permissions issue (?). Tried fixing the quotes - no dice. Directory/file aren't a problem (I don't think), because again I am having no errors when actually doing the deploy. I tried the temp agent option, and I get the same behavior (after the temp agent is copied). I tried `-whatif` and I don't get two passes on deployment (fewer items get "updated" when `-whatif` is enabled, only one pass seems to run then). – Merlyn Morgan-Graham Nov 09 '11 at 00:18
  • The files are expected to have different timestamps because I'v recreated them. That's why I'm syncing them. If you notice that the source files have a later timestamp than the destination files, that makes sense. The confusing part to me is that they don't get updated on the "first pass" but do on the "second pass". Why it is doing two passes baffles me. – Merlyn Morgan-Graham Nov 09 '11 at 05:12
  • I wrestled with what part of the logs to put up earlier, so much that I forgot to actually describe all the steps that were happening :) I added that to the bottom of the Q. – Merlyn Morgan-Graham Nov 09 '11 at 05:21
  • Okay got something working. Short answer: When using the `runCommand` provider, use batch files. For some reason this made it stop running two passes. The problem with this solution is that you can't specify the installation directory of the service via a SetParameters.xml file. I also finally found and tried the `dontUseCommandExe` option, but I figured out that option doesn't let you specify args to the exe. Your `preSync` option, etc, won't let you specify the directory in the SetParameters.xml either. So, I'm going to give up trying to make this perfect. MsDeploy is underbaked. :) – Merlyn Morgan-Graham Nov 09 '11 at 09:38
  • @MerlynMorgan-Graham thanks - I added that as EDIT 3 above for future reference :-) – Yahia Nov 09 '11 at 09:47
  • Aha, isolated why it retries completely, and `runCommand` with `dontUseCommandExe` wouldn't fix it, even if it would take parameters. There's a timeout that's happening on my service uninstall, even though I've set a significant `waitInterval`. That value is just the interval to *kill the process*, it is not an interval to avoid aborting the pass. I think the abort-pass interval is going to be like 1 second, and you can't override it. If it hits that size, then it will assume it can't copy files, will run the rest of your `runCommand` tasks, and try the whole thing over again. – Merlyn Morgan-Graham Nov 09 '11 at 10:30
  • I figured this out by playing with `retryAttempts` and `retryInterval`, as well as `waitAttempts`. It seems they have one more value they need to bind to a setting that they missed. I could fix that with `preSync` and `postSync`, but those wouldn't work with SetParameters.xml. Okay, totally done now, I promise :) Thanks for your help! – Merlyn Morgan-Graham Nov 09 '11 at 10:31
  • @MerlynMorgan-Graham you are welcome... added that too (EDIT 4)... For updating a Windows Service I would perhaps build 2 services (one updater and the real one)... the updater Service gets the new EXE, stops the other one, copies and starts it again... this way you can accomodate for any special situation like needing to wait longer or needing to check for some transaction processing to finish or whatever... – Yahia Nov 09 '11 at 10:38
  • I am having the same issue but using Powershell scripts in the runCommand stage. There are 2 sync passes. Also sometimes, the post runCommand runs before the sync. Its like the order cannot be guaranteed even though they appear in the order to be executed in the manifest. Have you any further advice how to solve this? – jaffa Feb 14 '14 at 16:51
0

I had the same problem, but I don't make package.zip file. I perform synchronization directly in one step. The preSync/postSync solution helped me a lot and there is no need to use manifest files. You can try the following command in your case:

"C:\Program Files\IIS\Microsoft Web Deploy V2\msdeploy"  
-verb:sync 
-preSync:runCommand="net stop TestSv && C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u
       C:\msdeploy\TestSvc\TestSvc\bin\Debug\TestSvc.exe",waitInterval=240000,waitAttempts=1 
-source:dirPath="C:\msdeploy\TestSvc\TestSvc\bin\Debug"
-dest:auto,computername=<computerNameHere>
-postSync:runCommand="C:\Windows\Microsoft.NET\Framework\v4.0.30319\installutil.exe
    C:\msdeploy\TestSvc\TestSvc\bin\Debug\TestSvc.exe && net start TestSvc",waitInterval=240000,waitAttempts=1

"-verb:sync" parameter means you synchronize data between a source and a destination. In your case your case, first time you perform synchronization between the "C:\msdeploy\TestSvc\TestSvc\bin\Debug" folder and the "package.zip". Plus, you are using manifest file, so when you perform second synchronization between the "package.zip" and the destination "computername", msbuild uses previously provided manifest twice for the destination and for the source, so each manifest operation runs twice. I used the && trick to perform several commands in one command line. Also, in my case, I had to add timeout operation to be sure the service were completely stopped ("ping -n 30 127.0.0.1 > nul").