I have a sample program from Aforge library. It uses a kind of logging system (I assume it is like a StringBuilder or something...).
In the samples, here and there I see something like:
IImageProcessingLog _log = new ImageProcessingLog();
//some code
_log.AddMessage("Image size: " + _bitmap.Width + " x " + _bitmap.Height);
//more codes and usage of `_log`
Clearly this is some sort of string. Later I want to dump all this data into a TextBox. I tried to do _log.ToString() but it just returns the object name.
Any idea how can I use this log feature?
Thanks
The ImageProcessingLog class has a property called Messages.
Messages is of type List<string>. So, to get all logged messages
simply iterate the elements of the messages list.
TextBox tbMessages = ...;
ImageProcessingLog log = new ImageProcessingLog();
log.AddMessage(...);
foreach(string msg in log.Messages)
{
tbMessages.Text += msg;
}
Unfortunately the IImageProcessingLog interface does not have such a property.
A possible workaround would be to create an adapter class/interface which wraps the
ImageProcessingLog class.
Related
I am new to C#. I am trying to get a list of subscriptions from an azure message bus:
ServiceBusAdministrationClient client = new ServiceBusAdministrationClient(connectionString);
var getSubResponse = client.GetSubscriptionsAsync(topicPath);
Console.WriteLine("subs:" + getSubResponse.AsPages());
The response is of type Task<IEnumerable<SubscriptionDescription>> or AsyncPageable<SubscriptionProperties>, depending on which documentation you read.
Visual Studio says the response type is Azure.Core.PageResponseEnumerator.FuncAsyncPageable<Azure.Messaging.ServiceBus.Administration.SubscriptionProperties>
How do I write some C# code to display every value in the response?
If I look at the response in Visual Studio debugger, it has hundreds of nested fields, none of which are the actual subscription info, they are just pointers etc. There is a Non-Public members field with _pageFunc, and below this are "Method" and "Target" and under target is another pageFunc which also has Method and Target.
Any ideas how I get useful info form such an object?
Ok, found the answer, its this:
var getSubResponse = client.GetSubscriptionsAsync(topicPath);
await foreach (var sub in getSubResponse)
{
Console.WriteLine("sub name:" + sub.SubscriptionName);
Console.WriteLine("sub ttl:" + sub.DefaultMessageTimeToLive);
Console.WriteLine("sub max delivery count:" + sub.MaxDeliveryCount);
}
There does not seem to be a way to dump all the fields unfortunately.
I am trying to access and modify DocumentProperties in Office (I try Word atm, but later on I want to expand to Excel, which shouldn't be a problem since the interop works quite similar), but at the moment I have the very concerning problem of not getting the type I would guess.
Here is a part of my code:
var testWordApp = new Word.Application();
var testWordFile = testWordApp.Documents.Open(
#"C:\Work\Intern\DocPropChanger_Projektarbeit\" +
#"PrototypeVorlagen\Proj-Nr_QPP_VersionVorlage_endeu.docx",
ReadOnly: false, Visible: false);
dynamic test = testWordFile.BuiltInDocumentProperties;
This code does give me the builtin DocumentProperties like last author, revision number and so on and I can go through it with an foreach, but it is different from what it should be.
MSDN and other sources clearly cast the returned object into an collection of DocumentProperties whereas if I do so aswell get an InvalidCastException.
I am currently working with VS 2015 Express and Office 13, but I already tried VSTO in VS 2015 Community with the same result.
https://msdn.microsoft.com/en-us/library/dhxe2d75.aspx
Here is a question by an other user in SO, who does (more or less)the same thing:
Accessing Excel Custom Document Properties programatically
It does seem to work for him, I have references to the proper parts of the framework, those are:
Office.Core
Office.Interop.Word
The main problem that results out of this inconvenience of having to use
dynamic
result in not being able to add my own Properties, which I try like that:
testWordFile.CustomDocumentProperties.Add(
Name: d.Name,
LinkToContent: false,
Type: 4,
Value: "Testtext aus Programm");
€: I also tried adding to test which turned out the same way.
This results in an exception:
HRESULT: 0x8000FFFF
This is after a short look in Google a pretty generic error.
What can I do to get the correct collection back? And am I doing a mistake while adding the property?
I looked among others (one of which is the linked above MSDN-page) at this sites for reference:
https://stackoverflow.com/a/12690798/3664953
€²:
For clearification:
I have to get every custom property that is set, even without knowing the name, so I didn't really find an approach other than to use the previously given approach in using dynamic and working with that.
As asked by Cindy Meister, I am currently NOT using VSTO but, also as previously stated, I already tried an approach with that, resulting in the same problems I am running into now, which can be linked in my inexperience with VSTO ...
Here is a more complete code from my class, just for the sake of it:
This is a prototype so all variables used are not named in a clearly understandable way, which shouldn't be a big problem, since the code isn't too complex atm.
var testWordApp = new Word.Application();
var testWordFile = testWordApp.Documents.Open(
#"C:\Work\Intern\DocPropChanger_Projektarbeit"+
#"\PrototypeVorlagen\Proj-Nr_QPP_VersionVorlage_endeu.docx",
ReadOnly: false, Visible: false);
dynamic test = testWordFile.BuiltInDocumentProperties;
Console.WriteLine(test.GetType());
foreach (dynamic d in test)
{
//TryCatch due to the fact, that I also get some more stuff, that are not Properties...
try
{
//I wanted to check the returned Types and if they have one at all
//This was something someone in the internet stated
//(Props not having a valid Type ...)
Console.WriteLine("\r\n---------\r\n");
Console.WriteLine(d.GetType());
Console.WriteLine(d.Name + " # " + d.Name.GetType());
Console.WriteLine(d.Type + " # " + d.Type.GetType());
Console.WriteLine(d.Value + " # " + d.Value.GetType());
}
catch
{ }
}
dynamic test2 = testWordFile.CustomDocumentProperties;
Console.WriteLine(test2.GetType());
foreach (dynamic d in test2)
{
try
{
Console.WriteLine("\r\n---------\r\n");
Console.WriteLine(d.GetType());
Console.WriteLine(d.Name + " # " + d.Name.GetType());
Console.WriteLine(d.Type + " # " + d.Type.GetType());
Console.WriteLine(d.Value + " # " + d.Value.GetType());
if(d.Name == "TestpropText")
{
//For highlighting
Console.WriteLine("#+#+#+#+#+#+#+#+#+#+#");
//This works like a charm
testWordFile.CustomDocumentProperties[d.Name].Delete();
//This results in the previously mentioned HRESULT: 0x8000FFFF
test.Add(Name: d.Name, LinkToContent: false, Type: 4, Value: "Testtext aus Programm");
}
}
catch(Exception e)
{
Console.WriteLine(e.InnerException);
}
}
testWordApp.Documents.Save(NoPrompt: true, OriginalFormat: true);
testWordApp.Application.Quit(SaveChanges: false, OriginalFormat: false,
RouteDocument: false);
I am attempting to launch AutoCAD 2013 from an existing C# desktop application, use database values to draw a diagram, and then save the drawing to the database as a variable bit array (varbyte). I've been having good success with all except getting coordinates into an existing AutoCAD editor window.
I've tried NETLOAD but I can't put a list of 55+ AutoCAD Database Circle objects through the command line. Attempting to pass objects through COM Interop has been met with failure and confusion over the 32-bit versus 64-bit status of AutoCAD and my application. While this site has been helpful, http://through-the-interface.typepad.com/ , I haven't been able to get what I want done.
Any suggestions would be greatly appreciated. Thanks.
EDIT:
I took Locke's advice and I added functions to the .NET DLL to draw single items based on simple arguments (like X, Y coordinates, radius, label, etc.). Here is what the method signature looks like:
[CommandMethod("DrawSmallCircle", CommandFlags.Session)]
public static void DrawSmallCircle(double x, double y, double aRadius, string aGuage, string aLabel, string aTitle)
After netloading the .dll which hosts the above method (and it's containing class), I use SendCommand on the instantiated interop AcadApplication like so:
acApp.ActiveDocument.SendCommand("DrawSmallCircle " +
circ.circle.Center.X.ToString() + ", " +
circ.circle.Center.Y.ToString() + ", " +
circ.circle.Radius.ToString() + ", " +
circ.guage + ", " +
circ.label + ", " +
circ.title + " "
);
Unfortunately the error I get in response is simply "Common Language Runtime detected an invalid program."
I'm not sure if registering a command in my .dll will do any good because, allegedly, "Command methods can't take arguments, but lispFunctions can."
http://forums.autodesk.com/t5/NET/CommandMethod-with-custom-params/td-p/2572973
Okay, so you've run into the Interop/In-Process automation issue. Traditionally, AutoCAD doesn't want to let out of process modules talk to in-process modules, at least in the context of sending parameters back and forth. The formal approach which involves registering the in-process COM interface is challenging to get behaving correctly, especially in the context of x64 bit. I've still yet to see it behave consistently across multiple computers, therefore I tend to default to the following approach.
You are correct in that methods flagged with the [CommandMethod] flag cannot take arguments, so they'll obviously need to be voids. The trick to sending it parameter context at runtime is to include parameter prompts in the defined method itself. Think of it as you're developing the command to be invoked by the user inside AutoCAD, and they are prompted for each piece of data before the command can proceed. Much like other native AutoCAD commands, the parameter data can be sent alongside the call to the command in a single string.
Example:
(Command "._CIRCLE" "0,0" "5") <-- Draws a circle at 0,0 with a radius of 5.
So your command call could end up looking something like this:
(Command "DRAWDBCIRCLE" "2.3,56.12", "7" "Gauge" "Label" "Title")
In-Process Code
[CommandMethod("DRAWDBCIRCLE")]
public void DrawDbCircle()
{
var acDb = HostApplicationServices.WorkingDatabase;
var acEd = Application.DocumentManager.MdiActiveDocument.Editor;
using (var acTrans = acDb.TransactionManager.StartOpenCloseTransaction())
{
var bt = (BlockTable)acTrans.GetObject(acDb.BlockTableId, OpenMode.ForWrite);
var btr = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
Point3d centerPoint;
double radius;
string gauge, label, title;
// Prompt for the centerpoint
var pointResult = acEd.GetPoint("ENTER CIRCLE ORIGIN: \n");
centerPoint = pointResult.Value;
// Prompt for the radius
var doubleResult = acEd.GetDouble("ENTER CIRCLE RADIUS: \n");
radius = doubleResult.Value;
// Prompt for the strings
var stringResult = acEd.GetString("ENTER CIRCLE GAUGE: \n");
gauge = stringResult.StringResult;
stringResult = acEd.GetString("ENTER CIRCLE LABEL: \n");
label = stringResult.StringResult;
stringResult = acEd.GetString("ENTER CIRCLE TITLE: \n");
title = stringResult.StringResult;
// Create the circle
var circ = new Circle(centerPoint, Vector3d.ZAxis, radius);
// <-- Add code for dealing with strings -->
btr.AppendEntity(circ);
acTrans.AddNewlyCreatedDBObject(circ, true);
acTrans.Commit();
}
}
Interop Code
private AcadApplication acApp;
private AcadDocument acDoc;
private void btnRun_Click(object sender, EventArgs e)
{
if (acApp == null) return;
acDoc = acApp.ActiveDocument;
foreach (DataRow row in circleTable.Rows)
DrawDatabaseCircle(row);
}
private void DrawDatabaseCircle(DataRow circRow)
{
var cmdFormat = string.Format("\"{0},{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\"", circRow.ItemArray);
acDoc.SendCommand(string.Format("(Command \"DRAWDBCIRCLE\" {0})\n", cmdFormat));
}
Obviously this is more or less pseudo-code. I assume a number of things here, like the AcadApplication and AcadDocument fields being set correctly, that the dll containing the defined command method has been properly netloaded, and that the database circles are coming out of a DataTable. Error-handling would be needed in the commandmethod for checking the parameters, and it would make sense to enclose the SendCommand method in a try/catch.
This technique really only works when you have data types that can be represented by strings, so it won't cover every situation. It's definitely worth trying to get the COM registered interface working long-term for more robust communication between in/out processes.
Is it possible to calculate the size of a (complexed) object (with dataContract) that I send over WCF? What I need is to calculate the size on both the request and the response objects and I need to do this in a winform application.
Could I maybe serlize the objects and then get the total size?
You can manually serialise / deserialise the objects yourself. Here's a simple example of serialisation and obtaining the length.
[DataContract(Name = "Person", Namespace = "http://www.woo.com")]
class Person
{
[DataMember()]
public string Name;
[DataMember()]
public int Age;
}
calling code (in a console app)
Person p = new Person();
p.Name = "Sean Cocteau";
p.Age = 99;
DataContractSerializer ds = new DataContractSerializer(p.GetType());
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
ds.WriteObject(ms, p);
// Spit out
Console.WriteLine("Output: " + System.Text.Encoding.UTF8.GetString(ms.ToArray()));
Console.WriteLine("Message length: " + ms.Length.ToString());
}
Console.ReadKey();
In respect to performing this automatically, say on each WCF call may involve you having to create your own Custom Binding that adds this to the message.
I think a message interceptor will help, you can add this endpoint behavior to the endpoint and handle httpwebrequest/response.
For more information, google WCF Message Interceptor, you'll find lots of useful things.
Hope this will help.
You can use svctraceviewer to trace both the activity and the message and then you can see the actual message flowing over WCF. However it seems that this tool might not get you the total size.
This post might help.
I have successfully connected to QC using VBscript via the OTA interface. In VbScript I had the following code to filter out defects and get load them in a list.
BugFilter.Filter("BG_STATUS") = "Not Canceled and NOT Closed"
BugFilter.Filter("BG_PROJECT") = "Business*"
Set BugList = BugFilter.NewList()
The above worked flawlessly in Vbscript.
In C#.NET (4.0), I am able to connect to QC successfully but when I try to apply the filter , it give me a error..
TDConnection qcc = new TDConnection();
qcc.InitConnectionEx(sr);
qcc.ConnectProjectEx("XXXX", "------", "----", "-----");
if (qcc.Connected)
{
Console.WriteLine("connected");
BugFactory bf = (BugFactory)qcc.BugFactory;
bf.Filter["BG_STATUS"] = "Not Canceled and NOT Closed";
bf.Filter["BG_PROJECT"] = "Business*";
List bugs = (List)bf.NewList(bf.Filter);
on the last line of code , it gives me the following error "Could not convert argument 0 for call to NewList."
I am relative new to C#, Can anybody help me here?
Try bg.Filter.text()
You'd need to check the method, 'cause I do that in java. But there is a method by that name. How I normally do that is like this:
List bugs = (List)bg.NewList();
I usually pass a string into the bug factory by using the .Text property of the Filter object rather than the filter object itself.
For example, I've had success with handling the filtering like this:
var tdFilter = (TDFilter)bf_filter;
tdFilter["BG_STATUS"] = "Not Canceled and NOT Closed";
tdFilter["BG_PROJECT"] = "Business*";
var bugs = bf.NewList(tdFilter.Text);