I have a Visual FoxPro (frx) report that is formatted to contain values from a query. It is planned to use this format as a template for PDF reports.
Is there a way to use it in a .NET application without any paying third party tool?
C# side collects the parameters, including the report Id to generate and save it to a .DAT file as XML. Then WGReport.exe is called passing the .dat name as a parameter. VFP exe WGReport, opens that .DAT file, decrypts (I send the content encrypted), runs the report, generates the PDF.
public JsonResult GenerateReport(string reportId)
{
var downloadInfo = new DownloadInfo
{
NoData = true,
Message = "",
FileName = "",
Id = ""
};
// Prepare reportParameters - as XML, report definition object ...
var result = CallReportCreator(ds.EncryptReportParameters(reportParameters), pdfName);
var reportName = report.ReportName;
if (result)
{
downloadInfo.NoData = false;
downloadInfo.Message = Url.Action("DownloadReport", "Report", new { reportid = pdfId, filename = report.ReportName });
downloadInfo.FileName = report.ReportName;
downloadInfo.Id = pdfId;
}
else
{
downloadInfo.NoData = true;
downloadInfo.Message = "No data found in given period.";
downloadInfo.FileName = "";
downloadInfo.Id = "";
}
return Json(downloadInfo, JsonRequestBehavior.AllowGet);
}
private bool CallReportCreator(string parameters, string resultPdf)
{
var exeName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "WGReport.exe");
var datName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", Guid.NewGuid().ToString("N") + ".dat");
System.IO.File.WriteAllText(datName, parameters);
ShellExecMyProcess(exeName, string.Format(@"""{0}""", datName), true, 60);
//System.IO.File.Delete(datName);
return System.IO.File.Exists(resultPdf);
}
private string ShellExecMyProcess(string fileName, string arguments, bool waitToExit = true, int timeOut = 60)
{
bool processExited = false;
DateTime start = DateTime.Now;
try
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = fileName;
psi.Arguments = arguments;
psi.CreateNoWindow = true;
psi.WindowStyle = ProcessWindowStyle.Hidden;
psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);
Process p = new Process();
p.EnableRaisingEvents = true;
p.Exited += (s, e) =>
{
processExited = true;
};
p.StartInfo = psi;
p.Start();
if (waitToExit)
{
while (!processExited && DateTime.Now < start.AddSeconds(timeOut))
{
Thread.Sleep(500);
}
return "success";
}
else
{
return "process called";
}
}
catch (Exception e)
{
return string.Format("error: [{0}]\n{1}", fileName, e.Message);
}
}
On VFP side main looks like:
Lparameters tcFileName
#include atrack.h
Set Exclusive Off
Set Safety Off
On Error Do ErrHandle With ;
ERROR( ), Message( ), Message(1), Program( ), Lineno( )
Return RunReport(m.tcFileName)
On Error
Procedure RunReport(m.tcFileName)
Local lcResult
lcResult = report_ForWG(m.loReportParameters)
Return m.lcResult
Endproc
report_ForWG(toReportParameters) is the process, running the report with given parameters and returning result string. In my case, lcResult is either 'No data found in given period.' or the name of the PDF filename that gets generated.