Puma.NET DLL Recognition of car numbers - c#

I want to make an application - license plate recognition from image. I use OpenCvSharp and Puma.NET.
But when I start my application,writes that the number is not found.
When I use breakpoints - Exception - "Recognition engine halted with code:0"
I loaded three dll - dibapi.dll, puma.net.dll, puma.interop.dll.
Why numbers are not recognized?
public void RecognizePlate() //
{
plateList.Clear();
int i = 1;
foreach(var plateImage in plate)
{
plateList.Add(i.ToString()+ " ) " + RunPuma(plateImage));
i++;
}
}
string RunPuma(IplImage img) //
{
PumaPage Image = new PumaPage(img.ToBitmap());
using (Image)
{
Image.FileFormat = PumaFileFormat.RtfAnsi;
Image.AutoRotateImage = true;
Image.FontSettings.DetectBold = true;
Image.FontSettings.DetectItalic = true;
Image.EnableSpeller = false;
Image.Language = PumaLanguage.English;
try
{
string s = Image.RecognizeToString();
return s;
}
catch(Exception e)
{
return "This is NOT NUMBER";
}
}
return "Error";
}`

You will need to restart Visual Studio as Administrator and you should be able to work then.

The problem is an unsuccessful registration.
According the documentation, apuma.dll component should be registered during the installation. But *.bat file seems to be wrong, at least for my computer.
I solved problem with:
moving all files from Puma.NET\COM Server\Register to Puma.NET\COM Server
open console in Puma.NET\COM Server directory.
Typing this command: regsvr32 APuma.dll
If you get a successful registration message, George is your uncle!!

Related

Visual Studio 2015 - EnvDTE Read ErrorList

I'm about to create a small Build Tool. The only things it should do: Try to Build the Solution and output the errors.
But not I have the following problem: In case the Build fails I cannot read the ErrorList. The program gets stuck and waits until forever.
I've created a small test Class which does nothing else than creating an instance of the Visual Studio 2015, build the given solution and read out the ErrorList on Build fail.
class Class1
{
DTE2 dte = (DTE2)System.Activator.CreateInstance(System.Type.GetTypeFromProgID("VisualStudio.DTE.14.0", true));
public void Test()
{
int id = dte.LocaleID;
//dte.MainWindow.Visible = true;
dte.Events.BuildEvents.OnBuildDone += new _dispBuildEvents_OnBuildDoneEventHandler(BuildEvents_OnBuildDone);
string solutionFile = #"C:\MyProjects\SolutionWithBuildErrors.sln";
dte.Solution.Open(solutionFile);
while (!dte.Solution.IsOpen)
System.Threading.Thread.Sleep(100);
Console.WriteLine("Start Build");
dte.Solution.SolutionBuild.Build(true);
Console.WriteLine("Finished Build");
dte.Quit();
}
private void BuildEvents_OnBuildDone(vsBuildScope Scope, vsBuildAction Action)
{
Console.WriteLine("BuildEvents_OnBuildDone Called");
int buildInfo = dte.Solution.SolutionBuild.LastBuildInfo;
switch (buildInfo)
{
case 0:
Console.WriteLine("Build erfolgreich");
break;
case 1:
Console.WriteLine("Build fehlerhaft");
getErrorList();
break;
}
}
private void getErrorList()
{
//dte.ExecuteCommand("View.ErrorList", " ");
Console.WriteLine("Lade Tool Windows");
ToolWindows tw = dte.ToolWindows;
Console.WriteLine("Geladen, Tool Windows");
Console.WriteLine("Lade ErrorList");
ErrorList el = tw.ErrorList;
Console.WriteLine("Geladen, ErrorList");
el.ShowErrors = true;
Console.WriteLine("Lese Error Liste");
//dte.ExecuteCommand("View.ErrorList", " ");
//ErrorItems errors = dte.ToolWindows.ErrorList.ErrorItems;
Console.WriteLine("#Errors: " + dte.ToolWindows.ErrorList.ErrorItems.Count);
for (int i = 1; i <= dte.ToolWindows.ErrorList.ErrorItems.Count; i++)
{
ErrorItem ei = dte.ToolWindows.ErrorList.ErrorItems.Item(i);
string errorLevel = "N/A";
errorLevel = ei.ErrorLevel.ToString();
string desc = "N/A";
if (ei.Description != null)
desc = ei.Description.ToString();
string file = "N/A";
if (ei.FileName != null)
file = ei.FileName.ToString();
string line = "N/A";
line = ei.Line.ToString();
string error = string.Format("{0}: {1}, File: {2}, Line: {3}", errorLevel, desc, file, line);
Console.WriteLine(error);
}
}
}
For testing purposes, just create a console application. In the main:
Class1 c1 = new Class1();
c1.Test();
Console.ReadLine();
Necessary Imports:
EnvDTE
EnvDTE80
I've already tried to run the Visual Studio in Visible-Mode and in case the Visual Studio Instance gets the focus while in the "wait for ErrorList Read" the ErrorList can be read.
If the Visual Studio never gets the focus (because running invisible or never click into while running visible) its not possible to receive the ErrorList.
Maybe there is another way to read out the ErrorList?
Just found the Solution I'm using =(
Maybe you can help me out or verify that there are really troubles with the ErrorList.
This is another way to get at the ErrorList - if that's really your problem:
EnvDTE.Window window = this.dte.Windows.Item(EnvDTE80.WindowKinds.vsWindowKindErrorList);
EnvDTE80.ErrorList sel = (EnvDTE80.ErrorList)window.Selection;
But both ways should be fairly equivalent. Microsoft did re-write Error List window implementation for VS 2015 - introducing some issues in the process, so I'd suggest trying your code against earlier versions.
Whether this issue has been Resolved or not I don't Know, But If its Exist Then Proceed with the ActiveX Concept To Solve this issue(More or less you can proceed with User Control ). Sure this issue will resolve I have done the same for my requirement.No need to Keep Focus on the respective Visual Studio

How to close a file in Autocad using C# keeping acad.exe running?

I am using visual studio 2010 and I am having a .DWG file which I want to open in autocad. Till now I have used this.
Process p = new Process();
ProcessStartInfo s = new ProcessStartInfo("D:/Test File/" + fileName);
p.StartInfo = s;
p.Start();
But what I want is to close the file inside the Autocad but not the autocad itself. (Means atocad.exe should be kept running).
Till now I hve used this but its closing the acad.exe not the file.
foreach (Process Proc in Process.GetProcesses())
{
if (Proc.ProcessName.Equals("acad"))
{
Proc.CloseMainWindow();
Proc.Kill();
}
}
Take the Autocad .NET libraries from Autodesk Sites (http://usa.autodesk.com/adsk/servlet/index?id=773204&siteID=123112)
Then you will be able to use Application and Document classes.
They will give you full control over opening and closing documents within the application.
You can find many articles on that, and can ask further questions.
AutoCAD does have an api. there are 4 assemblys. Two for in-process and two for COM.
inprocess :
acdbmgd.dll
acmgd.dll
COMInterop :
Autodesk.Autocad.Interop.dll
Autodesk.Autocad.Interop.Common.dll
this is a method that will open a new instance of AutoCAD or it will connect to an existing running instance of AutoCAD.
you will need to load these .dlls into your project references.
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
namespace YourNameSpace {
public class YourClass {
AcadApplication AcApp;
private const string progID = "AutoCAD.Application.18.2";// this is AutoCAD 2012 program id
private string profileName = "<<Unnamed Profile>>";
private const string acadPath = #"C:\Program Files\Autodesk\AutoCAD 2012 - English\acad.exe";
public void GetAcApp()
{
try
{
AcApp = (AcadApplication)Marshal.GetActiveObject(progID);
} catch {
try {
var acadProcess = new Process();
acadProcess.StartInfo.Arguments = string.Format("/nologo /p \"{0}\"", profileName);
acadProcess.StartInfo.FileName = (#acadPath);
acadProcess.Start();
while(AcApp == null)
{
try { AcApp = (AcadApplication)Marshal.GetActiveObject(progID); }
catch { }
}
} catch(COMException) {
MessageBox.Show(String.Format("Cannot create object of type \"{0}\"",progID));
}
}
try {
int i = 0;
var appState = AcApp.GetAcadState();
while (!appState.IsQuiescent)
{
if(i == 120)
{
Application.Exit();
}
// Wait .25s
Thread.Sleep(250);
i++;
}
if(AcApp != null){
// set visibility
AcApp.Visible = true;
}
} catch (COMException err) {
if(err.ErrorCode.ToString() == "-2147417846"){
Thread.Sleep(5000);
}
}
}
}
}
closeing it is as simple as
Application.Exit();
and forgive the code. its atrocious, this was one of my first methods when i just started developing...
I doubt you will be able to do this unless AutoCAD has an API that you can hook into and ask it to close the file for you.
Your c# app can only do things to the process (acad.exe) , it doesn't have access to the internal operations of that process.
Also, you shouldn't use Kill unless the process has become unresponsive and certainly not immediately after CloseMainWindow.
CloseMainWindow is the polite way to ask an application to close itself. Kill is like pulling the power lead from the socket. You aren't giving it the chance to clean up after itself and exit cleanly.
There is one other possibility - this will only work if your C# code is running on the same machine as the AutoCAD process and it is not really recommended, but, if you are really stuck and are prepared to put up with the hassle of window switching you can send key strokes to an application using the SendKeys command.
MSDN articles here:
http://msdn.microsoft.com/EN-US/library/ms171548(v=VS.110,d=hv.2).aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx
Using this you could send the key strokes to simulate the user using the menu commands to close the file.
To perform the closing of file, best way out is to follow the steps at this ObjectARX SDK for c# and change the following code with the below code.
[CommandMethod("CD", CommandFlags.Session)]
static public void CloseDocuments()
{
DocumentCollection docs = Application.DocumentManager;
foreach (Document doc in docs)
{
// First cancel any running command
if (doc.CommandInProgress != "" &&
doc.CommandInProgress != "CD")
{
AcadDocument oDoc =
(AcadDocument)doc.AcadDocument;
oDoc.SendCommand("\x03\x03");
}
if (doc.IsReadOnly)
{
doc.CloseAndDiscard();
}
else
{
// Activate the document, so we can check DBMOD
if (docs.MdiActiveDocument != doc)
{
docs.MdiActiveDocument = doc;
}
int isModified =
System.Convert.ToInt32(
Application.GetSystemVariable("DBMOD")
);
// No need to save if not modified
if (isModified == 0)
{
doc.CloseAndDiscard();
}
else
{
// This may create documents in strange places
doc.CloseAndSave(doc.Name);
}
}
}

C# code to change browser download options

I am trying to do following with c#.
1) Open Firefox Browser-->Tools-->Options-->General Tab--->Downloads--->Always ask me where to save file.
I want to do this whole process in my application with c#. I want that when download window opens, the radio button in "Always ask me where to save file" option gets checked automatically.
I have tried from various links, but all is in vain.
Here is the full code, console application.
Summary: preferences file is located in application roaming folder, something like this on windows 7:
C:\Users\MYNAME\AppData\Roaming\Mozilla\Firefox\Profiles\d9i9jniz.default\prefs.js
We alter this file so that it includes "user_pref("browser.download.useDownloadDir", false);"
Restart firefox, and done. Only run this application when firefox is not running.
static void Main(string[] args)
{
if (isFireFoxOpen())
{
Console.WriteLine("Firefox is open, close it");
}
else
{
string pathOfPrefsFile = GetPathOfPrefsFile();
updateSettingsFile(pathOfPrefsFile);
Console.WriteLine("Done");
}
Console.ReadLine();
}
private static void updateSettingsFile(string pathOfPrefsFile)
{
string[] contentsOfFile = File.ReadAllLines(pathOfPrefsFile);
// We are looking for "user_pref("browser.download.useDownloadDir", true);"
// This needs to be set to:
// "user_pref("browser.download.useDownloadDir", false);"
List<String> outputLines = new List<string>();
foreach (string line in contentsOfFile)
{
if (line.StartsWith("user_pref(\"browser.download.useDownloadDir\""))
{
Console.WriteLine("Found it already in file, replacing");
}
else
{
outputLines.Add(line);
}
}
// Finally add the value we want to the end
outputLines.Add("user_pref(\"browser.download.useDownloadDir\", false);");
// Rename the old file preferences for safety...
File.Move(pathOfPrefsFile, Path.GetDirectoryName(pathOfPrefsFile) + #"\" + Path.GetFileName(pathOfPrefsFile) + ".OLD." + Guid.NewGuid().ToString());
// Write the new file.
File.WriteAllLines(pathOfPrefsFile, outputLines.ToArray());
}
private static string GetPathOfPrefsFile()
{
// Get roaming folder, and get the profiles.ini
string iniFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\Mozilla\Firefox\profiles.ini";
// Profiles.ini tells us what folder the preferences file is in.
string contentsOfIni = File.ReadAllText(iniFilePath);
int locOfPath = contentsOfIni.IndexOf("Path=Profiles");
int endOfPath = contentsOfIni.IndexOf(".default", locOfPath);
int startOfPath = locOfPath + "Path=Profiles".Length + 1;
int countofCopy = ((endOfPath + ".default".Length) - startOfPath);
string path = contentsOfIni.Substring(startOfPath, countofCopy);
string toReturn = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\Mozilla\Firefox\Profiles\" + path + #"\prefs.js";
return toReturn;
}
public static bool isFireFoxOpen()
{
foreach (Process proc in Process.GetProcesses())
{
if (proc.ProcessName == "firefox")
{
return true;
}
}
return false;
}
What have you tried?
Firefox settings are stored in your profile, so I'd guess you can change the contents of the given file. Type about:config to find the setting you're looking for, I guess it's in the browser.download tree, alter it (after you made sure the browser isn't running) and you should be good to go.

How to redirect output from the NASM command line assembler in C#

Brief Summary
I am creating a lightweight IDE for NASM development in C# (I know kind of an irony). Kinda of like Notepad++ but simpler but with features that make it more than source editor. Since Notepad++ is really just a fancy source editor. I have already implemented features like Project creation (using a project format similar to how Visual Studio organizes projects). Project extension .nasmproj. I am also in the works of hosting it in an open-source place (Codeplex). Although the program is far from finish, and definitely cannot be used in a production environment without proper protection and equipment. In addition, I am working alone with it at this moment, more like a spare time project since I just finished my last Summer final taking Calculus I.
Problem
Right now I am facing a problem, I can build the project but no output from NASM is being fed into the IDE. I have succesfully built a project, and I was able to produce object files. I even tried producing a syntax error to see if I finally see something come up but none and I check the bin folder of the test project I created and I see no object file creating. So definitely NASM is doing its magic. Is it because NASM doesn't want me to see its output. Is there a solution? Any advice would be great. Here is the code which I think is giving Trouble.
Things to Note
I have already checked if events have been invoked. An yes they have but they return empty strings
I have also checked error data and same effect.
Code
public static bool Build(string arguments, out Process nasmP)
{
try
{
ProcessStartInfo nasm = new ProcessStartInfo("nasm", arguments);
nasm.CreateNoWindow = true;
nasm.RedirectStandardError = true;
nasm.RedirectStandardInput = true;
nasm.RedirectStandardOutput = true;
nasm.UseShellExecute = false;
nasmP = new Process();
nasmP.EnableRaisingEvents = true;
nasmP.StartInfo = nasm;
bool predicate = nasmP.Start();
nasmP.BeginOutputReadLine();
return true;
}
catch
{
nasmP = null;
return false;
}
}
//Hasn't been tested nor used
public static bool Clean(string binPath)
{
if (binPath == null || !Directory.Exists(binPath))
{
throw new ArgumentException("Either path is null or it does not exist!");
}
else
{
try
{
DirectoryInfo binInfo = new DirectoryInfo(binPath);
FileInfo[] filesInfo = binInfo.GetFiles();
for (int index = 0; index < filesInfo.Length; index++)
{
try
{
filesInfo[index].Delete();
filesInfo[index] = null;
}
catch
{
break;
}
}
GC.Collect();
return true;
}
catch
{
return false;
}
}
}
}
using (BuildDialog dlg = new BuildDialog(currentSolution))
{
DialogResult result = dlg.ShowDialog();
dlg.onOutputRecieved += new BuildDialog.OnOutputRecievedHandler(delegate(Process _sender, string output)
{
if (result == System.Windows.Forms.DialogResult.OK)
{
outputWindow.Invoke(new InvokeDelegate(delegate(string o)
{
Console.WriteLine("Data:" + o);
outputWindow.Text = o;
}), output);
}
});
}
Edits
I have tried doing synchronously instead of asynchronously but still the same result (and empty string "" is returned) actually by debugging the stream is already at the end. So looks like nothing has been written into the stream.
This is what I tried:
string readToEnd = nasmP.StandardOutput.ReadToEnd();
nasmP.WaitForExit();
Console.WriteLine(readToEnd);
And another interesting thing I have tried was I copied the arguments from the debugger and pasted it in the command line shell and I can see NASM compiling and giving the error that I wanted to see all along. So definitely not a NASM problem. Could it be a problem with my code or the .Net framework.
Here is a nice snapshot of the shell window (although not technically proof; this is what the output should look like in my IDE):
Alan made a very good point, check the sub processes or threads. Is sub process and thread synonymous? But here is the problem. Almost all the properties except a select few and output/error streams are throwing an invalid operation. Here is the debugger information as an image (I wish Visual Studio would allow you to copy the entire information in click):
Okay I finally was able to do it. I just found this control that redirect output from a process and I just looked at the source code of it and got what I needed to do. Here is the the modified code:
public static bool Build(string command, out StringBuilder buildOutput)
{
try
{
buildOutput = new StringBuilder();
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe");
startInfo.Arguments = "/C " + " nasm " + command;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process p = Process.Start(startInfo);
string output = p.StandardOutput.ReadToEnd();
string error = p.StandardError.ReadToEnd();
p.WaitForExit();
if (output.Length != 0)
buildOutput.Append(output);
else if (error.Length != 0)
buildOutput.Append(error);
else
buildOutput.Append("\n");
return true;
}
catch
{
buildOutput = null;
return false;
}
}
Here is how the output is formatted like:
I also wanted to thank Alan for helping me debug my code, although he didn't physically had my code. But he really was helpful and I thank him for it.

p4.net cannot connect Perforce

I am using p4.net API to generate some reports from the metadata.
In one of the reports, I need to generate then number of the changes lines for each changeset report.
As a reporting tool, I am using MS SQL Reporting services 2008, and I have written a custom dll that uses p4.net API to calculate the number of changed lines. it works on the local without any problem. However, when I run the code on the server, it calculates let's say first %20 part then starts throwing Unable to connect to the Perforce Server!
Unable to connect to Perforce! exception.
I try same credentials on the local, it works.. I use commandline with same credentials on the server, it works.
Could anyone help me with that please, if encountered before?
Here is the code I use. If needed
public static class PerforceLib
{
public static P4Connection p4conn = null;
private static void CheckConn()
{
try
{
if (p4conn == null)
{
p4conn = new P4Connection();
p4conn.Port = "address";
p4conn.User = "user";
p4conn.Password = "pwd*";
p4conn.Connect();
p4conn.Login("pwd");
}
else if (p4conn != null)
{
if(!p4conn.IsValidConnection(true, false))
{
Log("Check CONN : Connection is not valid, reconnecting");
p4conn.Login("pwd*");
}
}
}
catch (Exception ex )
{
Log(ex.Message);
}
}
public static int DiffByChangeSetNumber(string ChangeSetNumber)
{
try
{
CheckConn();
P4Record set = p4conn.Run("describe", "-s",ChangeSetNumber)[0];
string[] files = set.ArrayFields["depotFile"].ToArray<string>();
string[] revs = set.ArrayFields["rev"].ToArray<string>();
string[] actions = set.ArrayFields["action"].ToArray<string>();
int totalChanges = 0;
List<P4File> lstFiles = new List<P4File>();
for (int i = 0; i < files.Count(); i++)
{
if (actions[i].ToString() == "edit")
lstFiles.Add(new P4File() { DepotFile = files[i].ToString(), Revision = revs[i].ToString(), Action = actions[i].ToString() });
}
foreach (var item in lstFiles)
{
if (item.Revision != "1")
{
string firstfile = string.Format("{0}#{1}", item.DepotFile, (int.Parse(item.Revision) - 1).ToString());
string secondfile = string.Format("{0}#{1}", item.DepotFile, item.Revision);
P4UnParsedRecordSet rec = p4conn.RunUnParsed("diff2", "-ds", firstfile, secondfile);
if (rec.Messages.Count() > 1)
{
totalChanges = PerforceUtil.GetDiffResults(rec.Messages[1].ToString(), item.DepotFile);
}
}
}
GC.SuppressFinalize(lstFiles);
Log(string.Format("{0} / {1}", ChangeSetNumber,totalChanges.ToString() + Environment.NewLine));
return totalChanges;
}
catch (Exception ex)
{
Log(ex.Message + Environment.NewLine);
return -1;
}
}
}
your help will be appreciated
Many thanks
I have solved this issue. we identified that the code is circling through the ephemeral port range in around two minutes. once it reaches the maximum ephemeral port, it was trying to use same port again. Due to each perforce command creates a new socket, available ports were running out after it processed about 1000 changesets.
I have set the ReservedPorts value of HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters default(1433,143) that gave me larger range of ephemeral port.
and also implemented singleton pattern for P4Conn which helped as I dont close the connection. I only check the validity of the connection, and login if the connection is not valid.
Please let me know if any of you guys needs any help regarding this

Categories

Resources