Thursday, July 30, 2009

Communicating with legacy Source Code Control

Had a situation where I needed an old source control system written in Foxpro to pick up on file changes and consolidate them. The file changes could occur via any external package, but I was only interested in files in certain directories.

There were a couple of ways to handle the file once the change had been detected, but how to detect the change? The answer came by .Net's fileSystemWatcher. Run a .Net service that watches for changes. The next step was then how to communicate the changes to VFP, the answer there was sockets. I could have used interop, but the nice thing about sockets is that they are light.

The result was a simple event handler that detects a change and sends a message to the Source Code Control that it has something to process :


///
/// Track changes in the filesystem and pass them over to the legacy SCC system.
///

///
///
protected void writeFileEvent(object sender, FileSystemEventArgs e)
{
string cModFile = e.FullPath.ToString();
cModFile = cModFile.ToLower();
// Exclude files that don't have to be stored
if (cModFile.IndexOf("develop\\pending") != -1 ||
Path.GetExtension(cModFile) == "" ||
cModFile.IndexOf("develop\\bin") != -1 ||
cModFile.IndexOf("\\prog\\ide.log") != -1 ||
cModFile.IndexOf("\\prog\\symbols\\") != -1 ||
cModFile.IndexOf("\\prog") == -1){
return;
}
// Record the file to be processed
string cLogFile = "\\formwork\\develop\\pending\\" +
Guid.NewGuid().ToString() +".xml";
// Create an instance of StreamWriter to write text to a file.
// The using statement also closes the StreamWriter.
using (StreamWriter sw = new StreamWriter(cLogFile))
{
// Add some text to the file.
sw.Write("" +
"" +
cModFile + "
");
sw.Close();
}

//create a new client socket ...
// Don't really have to wait for a response.
// The file has been recorded (above) for processing
// so the next time the SCC starts it will pick up on the change anyway.
// However, if the SCC is running now let it know there is work to be done so
// it doesn't have to poll the directory.
Socket m_socClient = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
String szIPSelected = "127.0.0.1";
int alPort = 8000;

System.Net.IPAddress remoteIPAddress =
System.Net.IPAddress.Parse(szIPSelected);
System.Net.IPEndPoint remoteEndPoint =
new System.Net.IPEndPoint(remoteIPAddress, alPort);
m_socClient.Connect(remoteEndPoint);
String szData = cLogFile;
byte[] byData = System.Text.Encoding.ASCII.GetBytes(szData);
m_socClient.Send(byData);
m_socClient.Close ();
}

No comments: