我为Cruise Control .net创建了以下自定义任务,但是我找不到如何将自定义任务添加到项目配置的单一参考。有没有人有一个如何在cc.net中添加对自定义任务的引用的有用示例?
(以下是我的新任务)
public class RestoreDb : TaskBase
{
#region Parameters
[Required]
public string ServerName { get; set; }
[Required]
public string DbName { get; set; }
public string BackupFileName { get; set; }
#endregion
protected override bool Execute(ThoughtWorks.CruiseControl.Core.IIntegrationResult result)
{
bool returnResult = false;
try
{
SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder();
connectionStringBuilder.IntegratedSecurity = true;
connectionStringBuilder.DataSource = ServerName;
SqlConnection connection = new SqlConnection(connectionStringBuilder.ToString());
connection.Open();
Server server = new Server(new ServerConnection(connection));
if (server.Databases[DbName] != null)
{
Log.Info("Dropping existing " + DbName + " on " + ServerName);
server.Databases[DbName].Drop();
}
else
{
Log.Info(DbName + " on " + ServerName + " doesn't exist.");
}
Log.Info("Restoring " + DbName + " on " + ServerName);
Database newDb = new Database(server, DbName);
Restore rs = new Restore();
rs.NoRecovery = false;
FileInfo fi = new FileInfo(server.Settings.BackupDirectory + "\\" + BackupFileName);
rs.Devices.AddDevice(fi.FullName, DeviceType.File);
rs.Database = DbName;
rs.Action = RestoreActionType.Database;
rs.ReplaceDatabase = true;
DataTable fileContents = rs.ReadFileList(server);
string originalDbName = fileContents.Rows[0][0].ToString();
string originalLogFileName = fileContents.Rows[1][0].ToString();
rs.RelocateFiles.Add(new RelocateFile(originalDbName,
string.Format(@"C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\{0}.mdf", DbName)));
rs.RelocateFiles.Add(new RelocateFile(originalLogFileName,
string.Format(@"C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\{0}_1.ldf", DbName)));
rs.SqlRestore(server);
Log.Info("Restoring done.");
returnResult = true; // success!
}
catch (Exception ex)
{
Log.Error(ex);
returnResult = false;
}
return returnResult;
}
}
答案 0 :(得分:1)
你没有提到你正在使用的版本,所以我在假设用户将使用更新的版本时回答这个问题。我根据开发cruisecontrol.net 1.8.3.0
的自定义任务的经验构建了这个您可以在此处找到一些api documentation来创建和使用plugins: http://www.cruisecontrolnet.org/projects/ccnet/wiki/DevInfo_MakingPlugins
编辑:我想请注意,所提供链接上的CruiseControl.NET文档已经更新,现在包含了大部分信息。
但是,这个文档的重量相当轻,并没有涵盖您最终会在尝试创建自己的任务时遇到问题的主题范围。
这个过程,就像我可以说的那样;
您的自定义任务项目需要引用以下程序集,这些程序集可以在根CruiseControl.NET服务器文件夹中找到。
构建自定义任务时,您需要使用Reflector属性标记要公开的任何类或属性,以使它们在ccnet.config中可用
为了让CruiseControl.NET使用您的自定义库,您需要使用以下约定命名程序集:ccnet.WhateverYouWantHere.plugin.dll
您需要将此程序集放在CruiseControl.NET Server文件夹中。
namespace MyTasks
{
[ReflectorType("MyCustomTask")]
public class MyCustomTaskClass : ITask
{
[ReflectorProperty("MyCustomTaskProperty")]
public string CustomProperty { get; set; }
public string MyInternalPublicProperty { get; set; }
public void Run(IIntegrationResult result){}
}
}
注意:该属性的名称和您向ccnet.config公开的名称不必匹配。
为了引用创建的任务,标签符等,您只需使用Reflector属性中提供的字符串。
<project>
<tasks>
<MyCustomTask MyCustomTaskProperty="This is an example"/>
</tasks>
</project>
如果您尝试使用此代码,并在标记中添加对MyInternalPublicProperty的引用,则无效:
<project>
<tasks>
<MyCustomTask MyInternalPublicProperty="This is will throw an exception in the service and not reload the ccnet config until the invalid content is removed from the config"/>
</tasks>
</project>
这是因为你没有使用它自己的[ReflectorProperty()]属性来装饰属性。
答案 1 :(得分:0)
所以我基本上把它扔了,因为没有任何示例如何将自定义任务添加到cc.net配置。下面是我写的powershell脚本,它完成了相同的步骤。
$ServerName = 'servernamehere';
$DatabaseName = 'newDbNameHere';
$BackupFile = 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Backup\backupFileHere.bak';
if($args[0])
{
$ServerName = $args[0];
}
if($args[1])
{
$DatabaseName = $args[1];
}
if($args[2])
{
$BackupFile = $args[2];
}
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")
try
{
$Server = new-object ("Microsoft.SqlServer.Management.Smo.Server") $ServerName
If ($Server.Databases.Contains($DatabaseName))
{
write-host "Dropping existing " $DatabaseName " on " $ServerName;
#$Server.Databases[$DatabaseName].SetOffline();
$Server.Databases[$DatabaseName].Drop();
}
else
{
write-host $DatabaseName " on " $ServerName " doesn't exist.";
}
$Database = new-object ("Microsoft.SqlServer.Management.Smo.Database") ($Server, $DatabaseName);
$restore = new-object ('Microsoft.SqlServer.Management.Smo.Restore');
$restore.NoRecovery = $false;
$fil=new-object "Microsoft.SqlServer.Management.Smo.BackupDeviceItem";
$fil.DeviceType='File';
$fil.Name= $BackupFile;
$restore.Action="Database";
$restore.Devices.Add($fil);
$restore.Database=$DatabaseName;
$restore.ReplaceDatabase = $true;
#retrieving the backup file's original database values so we can replace them
$FileContents = $restore.ReadFileList($Server);
$originalDbName = $FileContents.Rows[0][0].ToString();
$originalLogFileName = $FileContents.Rows[1][0].ToString();
#replacing the bak files original file names with the new file names
$mdf = new-object "Microsoft.SqlServer.Management.Smo.RelocateFile" ($originalDbName,
"C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\$DatabaseName.mdf");
$restore.RelocateFiles.Add($mdf);
$ldf = new-object "Microsoft.SqlServer.Management.Smo.RelocateFile" ($originalLogFileName,
"C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\$DatabaseName_Log.mdf");
$restore.RelocateFiles.Add($ldf);
write-host "Restoring database $DatabaseName on $ServerName from file $BackupFile";
$restore.SqlRestore($Server);
write-host "Restore Complete";
}
catch [System.Exception] {
# $_ is set to the ErrorRecord of the exception
$currentException = $_.Exception;
write-host "Root Exception: " $currentException.Message;
While($currentException.InnerException)
{
$currentException = $_.Exception.InnerException;
write-host "Inner Exception: " $currentException.Message;
}
write-host "Restore Failed.";
exit 0; #failure
}
exit 1;