最近遭遇发布TimerJob在测试环境发布没有问题,但是到正式环境发布总是无法执行及调试的问题,经过几天的努力,终于解决了这个问题,下面记录下遭遇的问题。
Windows 2008,SharePoint 2013,测试环境为单机,生产环境为双AP,一DB。双AP中一个是AP+管理中心,另外一个只做索引爬网。
测试环境一切正常,可以执行调试,部署至于正式环境会碰到:错误 2 部署步骤“激活功能”中出现错误: Feature with Id 'xx' is not installed in this farm, and cannot be added to this scope.该错误正常,去管理中心部署解决方案至site即可。
下面问题来了,解决方案中有两个Feature,一个是包含了可视化的WebPart的,另外一个是激活后新建TimerJob的。TimerJob这个无法执行无法调试。
1、更改了TimerJob的名称,但是依旧在重新激活Feature后显示旧的TimerJob名称。
2、移除C:\Windows\Microsoft.NET\assembly\GAC_MSIL中相应的dll,依旧无法执行调试。
3、移除网站目录下bin目录的dll,依旧没解决。
4、整个盘搜索相关dll,全部删除,依旧没有解决。
5、。。。
以上皆重启多次IIS及Timer Service。
后终于想明白,这可能是Timer Job的缓存导致的,google搜索"sharepoint timerjob cache",果然发现:,:
- Stop Windows SharePoint Timer Service from Windows Services
- Open C:\ProgramData\Microsoft\SharePoint\Config\<<GUID>> folder
- Delete all the XML files inside the GUID folder.
- Open the Cache.ini file and change the value to 1.
- Save Cache.ini file
- Restart Windows SharePoint Timer Service from Windows Services
注意需要在每个APP上执行一次。
我的操作:先收回解决方案,再执行以上操作,再部署,激活,问题解决。
作者还做了个脚本:
# Clear the SharePoint Timer Cache## 2009 Mickey Kamp Parbst Jervin (mickeyjervin.wordpress.com)# 2011 Adapted by Nick Hobbs (nickhobbs.wordpress.com) to work with SharePoint 2010,# display more progress information, restart all timer services in the farm,# and make reusable functions. # Output program informationWrite-Host -foregroundcolor White ""Write-Host -foregroundcolor White "Clear SharePoint Timer Cache" #**************************************************************************************# References#**************************************************************************************[void][reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint")[void][reflection.assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")[void][reflection.assembly]::LoadWithPartialName("System")[void][reflection.assembly]::LoadWithPartialName("System.Collections")#************************************************************************************** #**************************************************************************************# Constants#**************************************************************************************Set-Variable timerServiceName -option Constant -value "SharePoint 2010 Timer"Set-Variable timerServiceInstanceName -option Constant -value "Microsoft SharePoint Foundation Timer" #**************************************************************************************# Functions#************************************************************************************** ## Stops the SharePoint Timer Service on each server in the SharePoint Farm.# #The SharePoint farm object.function StopSharePointTimerServicesInFarm([Microsoft.SharePoint.Administration.SPFarm]$farm){ Write-Host "" # Iterate through each server in the farm, and each service in each server foreach($server in $farm.Servers) { foreach($instance in $server.ServiceInstances) { # If the server has the timer service then stop the service if($instance.TypeName -eq $timerServiceInstanceName) { [string]$serverName = $server.Name Write-Host -foregroundcolor DarkGray -NoNewline "Stop '$timerServiceName' service on server: " Write-Host -foregroundcolor Gray $serverName $service = Get-WmiObject -ComputerName $serverName Win32_Service -Filter "DisplayName='$timerServiceName'" $serviceInternalName = $service.Name sc.exe \\$serverName stop $serviceInternalName > $null # Wait until this service has actually stopped WaitForServiceState $serverName $timerServiceName "Stopped" break; } } } Write-Host ""} ## Waits for the service on the server to reach the required service state.# This can be used to wait for the "SharePoint 2010 Timer" service to stop or to start# #The name of the server with the service to monitor.#The name of the service to monitor.#The service state to wait for, e.g. Stopped, or Running.function WaitForServiceState([string]$serverName, [string]$serviceName, [string]$serviceState){ Write-Host -foregroundcolor DarkGray -NoNewLine "Waiting for service '$serviceName' to change state to $serviceState on server $serverName" do { Start-Sleep 1 Write-Host -foregroundcolor DarkGray -NoNewLine "." $service = Get-WmiObject -ComputerName $serverName Win32_Service -Filter "DisplayName='$serviceName'" } while ($service.State -ne $serviceState) Write-Host -foregroundcolor DarkGray -NoNewLine " Service is " Write-Host -foregroundcolor Gray $serviceState} ## Starts the SharePoint Timer Service on each server in the SharePoint Farm.# #The SharePoint farm object.function StartSharePointTimerServicesInFarm([Microsoft.SharePoint.Administration.SPFarm]$farm){ Write-Host "" # Iterate through each server in the farm, and each service in each server foreach($server in $farm.Servers) { foreach($instance in $server.ServiceInstances) { # If the server has the timer service then start the service if($instance.TypeName -eq $timerServiceInstanceName) { [string]$serverName = $server.Name Write-Host -foregroundcolor DarkGray -NoNewline "Start '$timerServiceName' service on server: " Write-Host -foregroundcolor Gray $serverName $service = Get-WmiObject -ComputerName $serverName Win32_Service -Filter "DisplayName='$timerServiceName'" [string]$serviceInternalName = $service.Name sc.exe \\$serverName start $serviceInternalName > $null WaitForServiceState $serverName $timerServiceName "Running" break; } } } Write-Host ""} ## Removes all xml files recursive on an UNC path# #The SharePoint farm object.function DeleteXmlFilesFromConfigCache([Microsoft.SharePoint.Administration.SPFarm]$farm){ Write-Host "" Write-Host -foregroundcolor DarkGray "Delete xml files" [string] $path = "" # Iterate through each server in the farm, and each service in each server foreach($server in $farm.Servers) { foreach($instance in $server.ServiceInstances) { # If the server has the timer service delete the XML files from the config cache if($instance.TypeName -eq $timerServiceInstanceName) { [string]$serverName = $server.Name Write-Host -foregroundcolor DarkGray -NoNewline "Deleting xml files from config cache on server: " Write-Host -foregroundcolor Gray $serverName # Remove all xml files recursive on an UNC path $path = "\\" + $serverName + "\c$\ProgramData\Microsoft\SharePoint\Config\*-*\*.xml" Remove-Item -path $path -Force break } } } Write-Host ""} ## Clears the SharePoint cache on an UNC path# #The SharePoint farm object.function ClearTimerCache([Microsoft.SharePoint.Administration.SPFarm]$farm){ Write-Host "" Write-Host -foregroundcolor DarkGray "Clear the cache" [string] $path = "" # Iterate through each server in the farm, and each service in each server foreach($server in $farm.Servers) { foreach($instance in $server.ServiceInstances) { # If the server has the timer service then force the cache settings to be refreshed if($instance.TypeName -eq $timerServiceInstanceName) { [string]$serverName = $server.Name Write-Host -foregroundcolor DarkGray -NoNewline "Clearing timer cache on server: " Write-Host -foregroundcolor Gray $serverName # Clear the cache on an UNC path # 1 = refresh all cache settings $path = "\\" + $serverName + "\c$\ProgramData\Microsoft\SharePoint\Config\*-*\cache.ini" Set-Content -path $path -Value "1" break } } } Write-Host ""} #**************************************************************************************# Main script block#************************************************************************************** # Get the local farm instance[Microsoft.SharePoint.Administration.SPFarm]$farm = [Microsoft.SharePoint.Administration.SPFarm]::get_Local() # Stop the SharePoint Timer Service on each server in the farmStopSharePointTimerServicesInFarm $farm # Delete all xml files from cache config folder on each server in the farmDeleteXmlFilesFromConfigCache $farm # Clear the timer cache on each server in the farmClearTimerCache $farm # Start the SharePoint Timer Service on each server in the farmStartSharePointTimerServicesInFarm $farm