verbot 5 sdk - loading KnowledgeBases - c#

I'm looking for help from anyone who's worked with the verbot sdk.
I'm making a program that I want to use the LearnedKnowledge.vkb, Teacher.vkb, and any standard bot (julia, for example). Those who've used this before will know that with the rules in Teacher, you can essentially write responses to things that the bot doesn't understand, and train it on the fly.
I'm planning on using speech recognition and text-to-speech, but my problem right now is that after I load the knowledgebases, I can't seem to get any response from the bot.
Here's what I have: The Verbot5Library.dll, from verbots.sourceforge.net (I got the editor and player too, to make sure the files were working). In my program, I set up the variables as such:
Verbot5Engine verbot = new Verbot5Engine();
KnowledgeBase kb = new KnowledgeBase();
KnowledgeBaseItem kbi = new KnowledgeBaseItem();
State state = new State();
XMLToolbox xmlToolboxKB = new XMLToolbox(typeof(KnowledgeBase));
Then I initialize the verbot engine and load the kbs:
// using the xmlToolboxKB method I saw in this forum: http://www.verbots.com/forums/viewtopic.php?t=2984
kbi.Fullpath = #"C:\\[full path to kb...]\\";
kbi.Filename = "LearnedKnowledge.vkb";
kb = (KnowledgeBase)xmlToolboxKB.LoadXML(kbi.Fullpath + kbi.Filename);
verbot.AddKnowledgeBase(kb, kbi);
kbi.Filename = "julia.vkb";
kb = (KnowledgeBase)xmlToolboxKB.LoadXML(kbi.Fullpath + kbi.Filename);
verbot.AddKnowledgeBase(kb, kbi);
//trying to use LoadKnowledgeBase and LoadCompiledKnowledgeBase methods: verbot.LoadKnowledgeBase("C:\\[full path to kb...]\\LearnedKnowledge.vkb");
//verbot.LoadCompiledKnowledgeBase("C:\\[full path...]\\julia.ckb");
//verbot.LoadCompiledKnowledgeBase("C:\\[full path...]\\Teacher.ckb");
// set up state
state.CurrentKBs.Add("C:\\[full path...]\\LearnedKnowledge.vkb");
state.CurrentKBs.Add("C:\\[full path...]\\Teacher.vkb");
state.CurrentKBs.Add("C:\\[full path...]\\julia.ckb");
Finally, I attempt to get a response from the verbot engine:
Reply reply = verbot.GetReply("hello", state);
if (reply != null)
Console.WriteLine(reply.AgentText);
else
Console.WriteLine("No reply found.");
I know julia has a response for "hello", as I've tested it with the editor. But all it ever returns is "No reply found". This code has been taken from the example console program in the SDK download (as very little documentation is available). That's why I need some pointers from someone who's familiar with the SDK.
Am I not loading the KBs correctly? Do they all need to be compiled (.ckb) instead of the XML files (.vkb)? I've used the verbot.OnKnowledgeBaseLoadError event handler and I get no errors. I even removed the resource file Default.vsn needed to load the Teacher, and it throws an error when trying to load it so I'm pretty sure it's all loading correctly. So why do I always get "No reply found"?

resolved: see http://www.verbots.com/forums/viewtopic.php?p=13021#13021

Related

C# MagnetLink to torrent file

I am going crazy right now. Since all other questions are several years old and the MonoTorrent developers have gone MIA I really need your help.
What I am really stuck with is parsing the magnet link and downloading it.
This is my code:
public static void DownloadTorrent(string magnetLink)
{
MagnetLink link = new MagnetLink(magnetLink);
//URL stores the magnetlink
EngineSettings settings = new EngineSettings();
settings.AllowedEncryption = EncryptionTypes.All;
settings.SavePath = destination;
string torrentFilePath = torrentDestination;
if (!Directory.Exists(settings.SavePath))
Directory.CreateDirectory(settings.SavePath);
if (!Directory.Exists(torrentFilePath))
Directory.CreateDirectory(torrentFilePath);
//Create a new engine, give it some settings and use it.
ClientEngine engine = new ClientEngine(settings);
engine.ChangeListenEndpoint(new IPEndPoint(IPAddress.Any, 6969));
TorrentManager manager = new TorrentManager(link, engine.Settings.SavePath, new TorrentSettings(), torrentFilePath);
engine.Register(manager);
manager.Start();
Console.ReadLine();
}
And my magnet link is: "magnet:?xt=urn:btih:c6df2f47d033d54b054cafe7ef683ba167222d92&dn=Windows+XP+Professional+SP3+-+Activated&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969"
Now an error throws on the magnet link saying "No such host is known and referring to udp://exodus.desync.com:6969/"(Visual Studio is on swedish so that might not be a literal translation).
Visual Studio is marking tracker = new UdpClient(announceUrl.Host, announceUrl.Port); as the error source and it's located inside one of MonoTorrent's code files; UdpTracker.cs
I am trying to make a simple application and I am just stuck on this part.
Any help is greatly appreciated. It's one of my first times posting here so if I missed to mention anything just tell me and I will add it.
Thanks on forehand! Also pardon my english, I am not a native speaker.
Update: If you know another way of solving this even without MonoTorrnet - I will take any help I can.

Play .oni-File on loop in C# / WPF

I'd like to play a previously recordet *.oni-File in C#/WPF. While, with the help of this tutorial I was able to get to RGB- and Depth-Stream to show up on my UI, I don't know how to play an *.oni-file.
The OpenNI page mentions, that I'd just have to "connect" to the file instead of the device, but I can't find the proper piece of code to do so.
The openni::Device class provides an interface to a single physical hardware device (via a driver). It can also provide an interface to a simulated hardware device via a recorded ONI file taken from a physical device.
If connecting to an ONI file instead of a physical device, it is only required that the ONI recording be available on the system running the application, and that the application have read access to this file.
I also found some clues / discussions, but none of it did help much
C# problem with .oni player
OpenNI-dev: Not able to play the skeletonRec.oni
EDIT: I found a way to at least get the recording played using the SamplesConfig.xml. I just inserted the following code into the <ProductionNodes>:
<Recording file="\test.oni" playbackSpeed="1.0"/>
Sadly, that recording crashes to program when it's done playing - I'm now looking for a way to loop the recording...
EDIT 2: Just if anybody should be interested, I'm using those lines to set the recording on loop:
ScriptNode scriptNode;
context = Context.CreateFromXmlFile(path + "\\" + configuration, out scriptNode);
Player p = (Player)context.FindExistingNode(NodeType.Player);
if (p!=null) p.SetRepeat(true); //Make sure it's really a recording.
If anybody should need the code one day - I managed to load the file and play the recording without the need of a config file:
Context context = new Context();
// Add license
License license = new License();
license.Vendor = "vendor";
license.Key = "key";
context.AddLicense(license);
// Open file
context.OpenFileRecordingEx("record.oni");
// Set to repeat
Player p = (Player)context.FindExistingNode(NodeType.Player);
if (p != null) p.SetRepeat(true);

HASP HL working demo needed for C#

Okay. Well, I know this question has a good chance of being closed within the first 10 minutes, but I am going to ask it anyways for I have spent almost day and an half trying to find a solution. Still, I can't figure this one out. There is not much info on this on the Internet not even on the HASP (safenet) website although they have demos.
I have a HASP HL USB dongle. I try to convert their demo and test run it but for the life of me I simply can't get it to login even. It keeps raising Aladdin.HASP.HaspStatus.HaspDotNetDllBroken exception.
However, if I run the C version of their demo, it works perfectly.
Here is the Csharp version of my code:
Aladdin.HASP;
HASP myHasp = new HASP();
var thestatus = myHasp.Login(vender_code);
myHasp.Logout;
I would like to login to USB HASP and get its HaspID and the settings in its memory.
Thanks in advance,
It might be that you aren't having all dependencies for the HASP runtime. I'm packing with the app:
hasp_windows_NNNNN.dll (NNNNN = your number)
hasp_net_windows.dll
MSVCR71.DLL (added manually)
msvc runtime 80
One runtime library is required by HASP and it doesn't tell you which one unless you put it in the DEPENDS.EXE utility (you probably have you on your Visual Studio installation).
To log in (and read some bytes):
byte[] key = new byte[16];
HaspFeature feature = HaspFeature.FromFeature(4);
string vendorCode = "your vendor string, get it from your tools";
Hasp hasp = new Hasp(feature);
HaspStatus status = hasp.Login(vendorCode);
if (HaspStatus.StatusOk != status)
{
// no license to run
return false;
}
else
{
// read some memory here
HaspFile mem = hasp.GetFile(HaspFileId.ReadOnly);
mem.Read(key, 0, 16);
status = hasp.Logout();
if (HaspStatus.StatusOk != status)
{
//handle error
}
}
Hope it helps. My HASPed software works like a charm. BTW, wasn't able to put envelope around .NET app under no combination of settings.

.NET virus scanning API

I'm building a web application in which I need to scan the user-uploaded files for viruses.
Does anyone with experience in building something like this can provide information on how to get this up and running? I'm guessing antivirus software packages have APIs to access their functionality programatically, but it seems it's not easy to get a hand on the details.
FYI, the application is written in C#.
Important note before use:
Be aware of TOS agreement. You give them full access to everything: "When you upload or otherwise submit content, you give VirusTotal (and those we work with) a worldwide, royalty free, irrevocable and transferable licence to use, edit, host, store, reproduce, modify, create derivative works, communicate, publish, publicly perform, publicly display and distribute such content."
Instead of using a local Antivirus program (and thus binding your program to that particular Antivirus product and requesting your customers to install that Antivirus product) you could use the services of VirusTotal.com
This site provides a free service in which your file is given as input to numerous antivirus products and you receive back a detailed report with the evidences resulting from the scanning process. In this way your solution is no more binded to a particular Antivirus product (albeit you are binded to Internet availability)
The site provides also an Application Programming Interface that allows a programmatically approach to its scanning engine.
Here a VirusTotal.NET a library for this API
Here the comprensive documentation about their API
Here the documentation with examples in Python of their interface
And because no answer is complete without code, this is taken directly from the sample client shipped with the VirusTotal.NET library
static void Main(string[] args)
{
VirusTotal virusTotal = new VirusTotal(ConfigurationManager.AppSettings["ApiKey"]);
//Use HTTPS instead of HTTP
virusTotal.UseTLS = true;
//Create the EICAR test virus. See http://www.eicar.org/86-0-Intended-use.html
FileInfo fileInfo = new FileInfo("EICAR.txt");
File.WriteAllText(fileInfo.FullName, #"X5O!P%#AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*");
//Check if the file has been scanned before.
FileReport fileReport = virusTotal.GetFileReport(fileInfo);
bool hasFileBeenScannedBefore = fileReport.ResponseCode == ReportResponseCode.Present;
Console.WriteLine("File has been scanned before: " + (hasFileBeenScannedBefore ? "Yes" : "No"));
//If the file has been scanned before, the results are embedded inside the report.
if (hasFileBeenScannedBefore)
{
PrintScan(fileReport);
}
else
{
ScanResult fileResult = virusTotal.ScanFile(fileInfo);
PrintScan(fileResult);
}
... continue with testing a web site ....
}
DISCLAIMER
I am in no way involved with them. I am writing this answer just because it seems to be a good update for these 4 years old answers.
You can use IAttachmentExecute API.
Windows OS provide the common API to calling the anti virus software which is installed (Of course, the anti virus software required support the API).
But, the API to calling the anti virus software provide only COM Interface style, not supported IDispatch.
So, calling this API is too difficult from any .NET language and script language.
Download this library from here Anti Virus Scanner for .NET or add reference your VS project from "NuGet" AntiVirusScanner
For example bellow code scan a file :
var scanner = new AntiVirus.Scanner();
var result = scanner.ScanAndClean(#"c:\some\file\path.txt");
Console.WriteLine(result); // console output is "VirusNotFound".
I would probably just make a system call to run an independent process to do the scan. There are a number of command-line AV engines out there from various vendors.
Take a look at the Microsoft Antivirus API. It makes use of COM, which should be easy enough to interface with from .NET. It refers specifically to Internet Explorer and Microsoft Office, but I don't see why you wouldn't be able to use to to on-demand scan any file.
All modern scanners that run on Windows should understand this API.
Various Virus scanners do have API's. One I have integrated with is Sophos. I am pretty sure Norton has an API also while McAfee doesn't (it used to). What virus software do you want to use? You may want to check out Metascan as it will allow integration with many different scanners, but there is an annual license cost. :-P
I also had this requirement. I used clamAv anti virus which provides on-demand scanning by sending the file to their tcp listening port. You can use nClam nuget package to send files to clamav.
var clam = new ClamClient("localhost", 3310);
var scanResult = clam.ScanFileOnServerAsync("C:\\test.txt"); //any file you would like!
switch (scanResult.Result.Result)
{
case ClamScanResults.Clean:
Console.WriteLine("The file is clean!");
break;
case ClamScanResults.VirusDetected:
Console.WriteLine("Virus Found!");
Console.WriteLine("Virus name: {0}", scanResult.Result.InfectedFiles[0].FileName);
break;
case ClamScanResults.Error:
Console.WriteLine("Woah an error occured! Error: {0}", scanResult.Result.RawResult);
break;
}
A simple and detailed example is shown here. Note:- The synchronous scan method is not available in the latest nuget. You have to code like I done above
For testing a virus you can use the below string in a txt file
X5O!P%#AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
Shameless plug but you might want to check out https://scanii.com, it's basically malware/virus detection as a (REST) service. Oh also, make sure you read and understand virustotal's API terms (https://www.virustotal.com/en/documentation/public-api/) - they are very clear about not allowing commercial usage.
I would recommend using this approach:
using System;
using System.Diagnostics;
using Cloudmersive.APIClient.NET.VirusScan.Api;
using Cloudmersive.APIClient.NET.VirusScan.Client;
using Cloudmersive.APIClient.NET.VirusScan.Model;
namespace Example
{
public class ScanFileAdvancedExample
{
public void main()
{
// Configure API key authorization: Apikey
Configuration.Default.AddApiKey("Apikey", "YOUR_API_KEY");
var apiInstance = new ScanApi();
var inputFile = new System.IO.FileStream("C:\\temp\\inputfile", System.IO.FileMode.Open); // System.IO.Stream | Input file to perform the operation on.
var allowExecutables = true; // bool? | Set to false to block executable files (program code) from being allowed in the input file. Default is false (recommended). (optional)
var allowInvalidFiles = true; // bool? | Set to false to block invalid files, such as a PDF file that is not really a valid PDF file, or a Word Document that is not a valid Word Document. Default is false (recommended). (optional)
var allowScripts = true; // bool? | Set to false to block script files, such as a PHP files, Pythong scripts, and other malicious content or security threats that can be embedded in the file. Set to true to allow these file types. Default is false (recommended). (optional)
var allowPasswordProtectedFiles = true; // bool? | Set to false to block password protected and encrypted files, such as encrypted zip and rar files, and other files that seek to circumvent scanning through passwords. Set to true to allow these file types. Default is false (recommended). (optional)
var restrictFileTypes = restrictFileTypes_example; // string | Specify a restricted set of file formats to allow as clean as a comma-separated list of file formats, such as .pdf,.docx,.png would allow only PDF, PNG and Word document files. All files must pass content verification against this list of file formats, if they do not, then the result will be returned as CleanResult=false. Set restrictFileTypes parameter to null or empty string to disable; default is disabled. (optional)
try
{
// Advanced Scan a file for viruses
VirusScanAdvancedResult result = apiInstance.ScanFileAdvanced(inputFile, allowExecutables, allowInvalidFiles, allowScripts, allowPasswordProtectedFiles, restrictFileTypes);
Debug.WriteLine(result);
}
catch (Exception e)
{
Debug.Print("Exception when calling ScanApi.ScanFileAdvanced: " + e.Message );
}
}
}
}
Note that this way you can even control whether you filter out non-virus threat payloads such as executables, scripts, encrypted/password-protected files, etc.
This approach has a free tier and can also validate the contents of the files that you upload.
We tried two options:
clamav-daemon installed on a tiny linux container + "nClam" .NET library to interact with it. Works fine, but Clam AV misses a lot (a lot!) of viruses, especially dangerous macros hidden in MS Office files. Also ClamAV virus database has to be kept in memory at all times, which uses around 3.5GB of memory, which requires a rather expensive cloud virtual machine.
Ended up using Windows Defender via MpCmdRun.exe CLI api. See answer here
You can try to use DevDragon.io.
It is a web service with an API and .NET client DevDragon.Antivirus.Client you can get from NuGet. Scans are sub 200ms for 1MB file.
More documentation here:
https://github.com/Dev-Dragon/Antivirus-Client
Disclosure: I work for them.
From my experience you can use COM for interfacing with some anti-virus software. But what I would suggest is a bit easier, just parse scan results after scanning. All you need to do is to start the scanner process and point it to file/folder you want to scan, store scan results into file or redirect stdout to your application and parse results.
//Scan
string start = Console.ReadLine();
System.Diagnostics.Process scanprocess = new System.Diagnostics.Process();
sp.StartInfo.WorkingDirectory = #"<location of your antivirus>";
sp.StartInfo.UseShellExecute = false;
sp.StartInfo.FileName = "cmd.exe";
sp.StartInfo.Arguments = #"/c antivirusscanx.exe /scan="+filePath;
sp.StartInfo.CreateNoWindow = true;
sp.StartInfo.RedirectStandardInput = true;
sp.StartInfo.RedirectStandardError = true; sp.Start();
string output = sp.StandardOutput.ReadToEnd();
//Scan results
System.Diagnostics.Process pr = new System.Diagnostics.Process();
pr.StartInfo.FileName = "cmd.exe";
pr.StartInfo.Arguments = #"/c echo %ERRORLEVEL%";
pr.StartInfo.RedirectStandardInput = true;
pr.StartInfo.RedirectStandardError = true; pr.Start();
output = processresult.StandardOutput.ReadToEnd();
pr.Close();

What is the Fastest way to read event log on remote machine?

I am working on an application which reads eventlogs(Application) from remote machines. I am making use of EventLog class in .net and then iterating on the Log entries but this is very slow. In some cases, some machines have 40000+ log entries and it takes hours to iterate through the entries.
what is the best way to accomplish this task? Are there any other classes in .net which are faster or in any other technology?
Man, I feel your pain. We had the exact same issue in our app.
Your solution has a branch depending on what server version you're running on and what server version your "target" machine is running on.
If you're both on Vista or Windows Server 2008, you're in luck. You should look at System.Diagnostics.Eventing.Reader.EventLogQuery and System.Diagnostics.Eventing.Reader.EventLogReader. These are new in .net 3.5.
Basically, you can build a query in XML and ship it over to run on the remote computer. Maybe you're just searching for events of a specific type, or maybe just new events from a specific point in time. The search runs on the remote machine, and then you just get back the matching events. The new classes are much faster than the old .net 2.0 way, but again, they are only supported on Vista or Windows Server 2008.
For our app when the target is NOT on Vista/Win2008, we downloaded the raw .evt file from the remote system, and then parsed the file using its binary format. There are several sources of data about the event log format for .evt files (pre-Vista), including link text and an article I recall on codeproject.com that had some c# code.
Vista and Windows Server 2008 machines use a new .evtx format that is a new format, so you can't use the same binary parsing approach across all versions. But the new EventLogQuery and EventLogReader classes are so fast that you won't have to. It's now perfectly speedy to just use the built-in classes.
Event Log Reader is horribly slow... too slow. WTF Microsoft?
Use LogParser 2.2 - Search for C# and LogParser on the Internet (or you can use the log parser commands from the command line). I don't want to duplicate the work already contributed by others.
I pull the log from the remote system by having the log exported as an EVTX file. I then copy the file from the remote system. This process is really quick - even with a network that spans the planet (I had issues with having the log exported to a network resource). Once you have it local, you can do your searches and processing.
There are multiple reasons for having the EVTX - I won't get into the reasons why we do this.
The following is a working example of the code to save a copy of the log as an EVTX:
(Notes: "device" is the network host name or IP. "LogName" is the name of the log desired: "System", "Security", or "Application". outputPathOnRemoteSystem is the path on the remote computer, such as "c:\temp\%hostname%.%LogName%.%YYYYMMDD_HH.MM%.evtx".)
static public bool DumpLog(string device, string LogName, string outputPathOnRemoteSystem, out string errMessage)
{
bool wasExported = false;
string errorMessage = "";
try
{
System.Diagnostics.Eventing.Reader.EventLogSession els = new System.Diagnostics.Eventing.Reader.EventLogSession(device);
els.ExportLogAndMessages(LogName, PathType.LogName, "*", outputPathOnRemoteSystem);
wasExported = true;
}
catch (UnauthorizedAccessException e)
{
errorMessage = "Unauthorized - Access Denied: " + e.Message;
}
catch (EventLogNotFoundException e)
{
errorMessage = "Event Log Not Found: " + e.Message;
}
catch (EventLogException e)
{
errorMessage = "Export Failed: " + e.Message + ", Log: " + LogName + ", Device: " + device;
}
errMessage = errorMessage;
return wasExported;
}
A good Explanation/Example can be found on MSDN.
EventLogSession session = new EventLogSession(Environment.MachineName);
// [System/Level=2] filters out the errors
// Where "Log" is the log you want to get data from.
EventLogQuery query = new EventLogQuery("Log", PathType.LogName, "*[System/Level=2]");
EventLogReader reader = new EventLogReader(query);
for (EventRecord eventInstance = reader.ReadEvent();
null != eventInstance;
eventInstance = reader.ReadEvent())
{
// Output or save your event data here.
}
When waiting 5-20 minutes with the old code this one does it in less than 10 seconds.
Maybe WMI can help you:
WMI with C#
Have you tried using the remoting features in powershell 2.0? They allow you to execute cmdlets (like ones to read event logs) on remote machines and return the results (as objects, of course) to the calling session.
You could place a Program at those machines that save the log to file and sends it to your webapplication i think that would be alot faster as you can do the looping local but im not sure how to do it so i cant ive you any code :(
I recently did such thing via WCF callback interface however my clients interacted with the server through WCF and adding a WCF Callback was easy in my project, full code with examples is available here
Just had the same issue and want to share my solution. It makes a search through application, system and security eventlogs from 260 seconds (using EventLog) about a 100 times faster (using EventLogQuery).
And this in a way where it is possible to check if the event message contains a pattern or any other check without the requirement of FormatDescription().
My trick is to use the same mechanism as PowerShells Get-WinEvent does and then pass it through the result check.
Here is my code to find all events within last 4 days where the event message contains a filter pattern.
string[] eventLogSources = {"Application", "System", "Security"};
var messagePattern = "*Your Message Search Pattern*";
var timeStamp = DateTime.Now.AddDays(-4);
var matchingEvents = new List<EventRecord>();
foreach (var eventLogSource in eventLogSources)
{
var i = 0;
var query = string.Format("*[System[TimeCreated[#SystemTime >= '{0}']]]",
timeStamp.ToUniversalTime().ToString("o"));
var elq = new EventLogQuery(eventLogSource, PathType.LogName, query);
var elr = new EventLogReader(elq);
EventRecord entryEventRecord;
while ((entryEventRecord = elr.ReadEvent()) != null)
{
if ((entryEventRecord.Properties)
.FirstOrDefault(x => (x.Value.ToString()).Contains(messagePattern)) != null)
{
matchingEvents.Add(entryEventRecord);
i++;
}
}
}
Maybe that the remote computers could do a little bit of computing. So this way your server would only deal with relevant information. It would be a kind of cluster using the remote computer to do some light filtering and the server would the the analysis part.

Categories

Resources