|
.NET Book Zero[^] is a free downloadable PDF. I recommend it even for experienced programmers converting from other languages.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Thank you. I'll have a look
Regards.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpfull answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
I know you asked about C#, but for mathematical problems MatLab is probably what you want...But MatLab is expensive!
So, consider looking at Octave http://www.gnu.org/software/octave/[^] which is a free implementation of a MatLab clone. It's not hard to learn, especally if you're more the mathematical type than the programmer type. (E.g., array indices are 1-based vs. 0-based, full matrix and vector operations, ...)
|
|
|
|
|
Thanks for all the recommendations.
As for MatLab, I have access to it, however I need my code to be integrated into our in house sim software and this will be in C#. I have seen a book for utilizing C# and MatLab together however I assume it is a bit too early to read that book!
If anyone thinks of any other books please do not hesitate to drop a line.
Thank you again.
|
|
|
|
|
Hello all,
I am developing a small utility that performs an action on files. This action may be very much ad-hoc, and so I want to be able to program it apart from the utility. The idea is that the utility loads the ad-hoc assembly when a class in it implements a certain interface, which the utility will call by invoking the interface method on a private reference of it, loaded with Activator.CreateInstance(). The interface is defined in another assembly, referenced by both the utility and the plug-in.
All compiles fine, but I get a run-time exception from down under the .NET hood (i.e. a native Windows error code HRESULT=0x80131047). Debugging info shows that the plug-in assembly is duly found and opened, but the utility could not load it "or one of its dependencies".
All my research up to now tells me to include version and public key info in specifying the plug-in but that would defeat the whole point of this set-up.
Has anybody any idea how I can get this to work ? Thanks for your help.
Michiel Rademakers
|
|
|
|
|
How are you loading the assembly?
It sounds like you might be using Assembly.LoadFile, which does not resolve dependencies. Use Assembly.LoadFrom or Assembly.Load instead.
Alan.
|
|
|
|
|
Your assumption was right.
I have tried Assembly.Load(...) and Assembly.LoadFrom(...) but now the found assembly throws a FileLoadException trying to load the plug-in, basically the same as before. If I catch it my utility ends with all plug-ins marked unusable
Must try some more.
Thanks a lot for your advice.
|
|
|
|
|
Rather than rolling your own mechanism, I'd suggest that you might want to look into MEF[^].
|
|
|
|
|
You are dead right. I will try this one.
Thanks.
|
|
|
|
|
MJL Rademakers wrote: Activator.CreateInstance()
I never use that, here's what I currently use:
namespace PIEBALD.Lib
{
public static partial class LibSys
{
public static System.Reflection.Assembly
DynamicLoad
(
string Filename
)
{
System.Reflection.Assembly result ;
System.IO.FileInfo fil = PIEBALD.Lib.LibFil.GetExpandedFileInfo ( Filename ) ;
try
{
/*\
|*| This is the common way to load an assembly:
|*| result = System.Reflection.Assembly.LoadFrom ( Filename ) ;
|*|
|*| The following is my take on a technique suggested by Sacha Barber:
\*/
result = System.AppDomain.CreateDomain
( System.IO.Path.GetFileNameWithoutExtension ( fil.Name ) ).
Load ( System.IO.File.ReadAllBytes ( fil.FullName ) ) ;
}
catch ( System.Exception err )
{
throw ( new System.InvalidOperationException
(
System.String.Format
(
"Could not load an assembly from file {0}"
,
Filename
)
,
err
) ) ;
}
return ( result ) ;
}
}
public static partial class LibSys
{
public static T
DynamicLoad<T>
(
string Filename
,
string Typename
,
params object[] Parameters
)
{
T result = default(T) ;
System.Reflection.Assembly assm = DynamicLoad ( Filename ) ;
System.Type type = assm.GetType ( Typename ) ;
if ( type == null )
{
throw ( new System.InvalidOperationException
(
System.String.Format
(
"The assembly in file {0} does not contain a public type named {1}"
,
Filename
,
Typename
)
) ) ;
}
if ( !typeof(T).IsAssignableFrom ( type ) )
{
throw ( new System.InvalidOperationException
(
System.String.Format
(
"Type {0} in file {1} does not implement or derive from {2}"
,
type.Name
,
Filename
,
typeof(T).FullName
)
) ) ;
}
System.Reflection.ConstructorInfo cons = type.GetConstructor
(
PIEBALD.Lib.LibSys.GetTypes ( Parameters ).ToArray()
) ;
if ( cons == null )
{
throw ( new System.InvalidOperationException
(
System.String.Format
(
"Type {0} in file {1} does not have the specified constructor"
,
type.Name
,
Filename
)
) ) ;
}
try
{
result = (T) cons.Invoke
(
Parameters
) ;
}
catch ( System.Exception err )
{
throw ( new System.InvalidOperationException
(
System.String.Format
(
"Unable to instantiate a {0}"
,
type.FullName
)
,
err
) ) ;
}
return ( result ) ;
}
}
}
|
|
|
|
|
Nothing wrong with Activator.CreateInstance if you specify that plugins should provide a parameterless constructor. I often use that and specify an Init method on the interface.
Here's what I use to load plugins in my game lobby client[^]:
107 public class PluginLoader : MarshalByRefObject {
108 Assembly a;
109 public PluginLoader(){
110 System.Runtime.Remoting.Lifetime.LifetimeServices.LeaseTime = new TimeSpan(1000, 0, 0, 0);
111 }
112
113 public void SetAssembly(string filename){
114 a = Assembly.LoadFrom(filename);
115 if(a == null) throw new PluginLoadException("Assembly "+filename+" not found or not valid");
116 }
117
118 public Type GetFirstType(Assembly a, Type type){
119 foreach(Module mod in a.GetLoadedModules()){
120 foreach(Type ty in mod.GetTypes()){
121 foreach(Type intf in ty.GetInterfaces()){
122 if(intf == type){
123 return ty;
124 }
125 }
126 }
127 }
128 return null;
129 }
130
131 public IGameType GetClientsideInfo(){
132 Type ty = GetFirstType(a, typeof(IGameType));
133 if(ty == null) return null;
134 return (IGameType)a.CreateInstance(ty.FullName);
135 }
136
137 public static PluginLoader Make(PluginInfo pi){
138 AppDomainSetup setup = new AppDomainSetup();
139 setup.ApplicationName = "Plugins";
140 setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
141 pi.domain = AppDomain.CreateDomain("plugin", null, setup);
142 pi.domain.DomainUnload += new EventHandler(DomainUnload);
143 PluginLoader loader = (PluginLoader)pi.domain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "RedCorona.GameClient.PluginLoader");
144
145 return loader;
146 }
147
148 public static void DomainUnload(object sender, EventArgs ea){
149 Console.WriteLine("Plugin domain "+sender+" unloaded!");
150 }
151
152 }
used like
46 public static IGameType LoadContent(String filename){
60 PluginInfo pi = new PluginInfo();
61 PluginLoader loader = PluginLoader.Make(pi);
62 loader.SetAssembly(filename);
63 return loader.GetClientsideInfo();
64 }
|
|
|
|
|
BobJanova wrote: specify an Init method
Except that an instance should be meaningful and usable once it's constructed. I don't like the Initialize pattern, the Create pattern is OK.
|
|
|
|
|
That's a triumph of ideology over pragmatism considering that you can't specify a constructor signature in an interface, in my opinion. In your code you are going to get a runtime exception if the class correctly implements the interface but doesn't have the right constructor, and to me that is a more important breakage of design (objects and method call dispatch should be compile-time type safe) than having a partially initialised object for a few lines.
|
|
|
|
|
BobJanova wrote: you are going to get a runtime exception
Yes, I throw it with a meaningful message. Yours will have to do something similar as well if a suitable implementation isn't found; it's just a cost of using plug-ins.
|
|
|
|
|
I want to get exception when I am running a script on virtual machine. I use VIX API and RunScriptInGuest...
because I need wscript.exe and if I have an error on myScript.vbs I can't handle the error because I am not receving any error because wscript.exe runs correctly.
vm.RunScriptInGuest("c:\perl\wscript.exe", script_path, 0, Nothing, Nothing)
Thank you very much
|
|
|
|
|
Does this have something to do with C#?
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Of corse! Because my code is in c# and I am using c# libraries
|
|
|
|
|
belea17 wrote: I want to get exception when I am running a script on virtual machine. I use VIX API and RunScriptInGuest...
because I need wscript.exe and if I have an error on myScript.vbs I can't handle the error because I am not receving any error because wscript.exe runs correctly.
vm.RunScriptInGuest("c:\perl\wscript.exe", script_path, 0, Nothing, Nothing)
You want to get an exception "where"? From "what"? Why? Trying to see if you're in a VM?
|
|
|
|
|
Hello all, I am deeply sorry that my first post is a (most likely) pretty stupid question, but I just can't work it out.
Say I have three labels label 1, label 2 and label 3.
Also I have a listbox listBox1 with item1, item2 and item3.
listBox1.SelectionMode is MultiSimple.
If e.g. the list box items 1 and 3 are selected (highlighted) I want the labels 1 and 3 to be visible.
Pretty simple. But I just have a knot in my brain.
One of my tries was that:
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listBox1.SelectedIndex == 0)
label1.Visible = true;
else
label1.Visible = false;
if (listBox1.SelectedIndex == 1)
label2.Visible = true;
else
label2.Visible = false;
}
Seemed okay to me. But: label2 visibility is only switching regarding to the listbox if item1 is selected.
What would be a good and simple way to accomplish what I want to do?
Really appreciate your help,
thanks
Dennis
|
|
|
|
|
When multiple selections are involved the SelectedIndexChanged event will only tell you that something has changed and the SelectedIndex property won't be of much use.
As you need to know both what is selected and what isn't selected you should iterate through the whole Items collection and get the selection state of each item using the GetSelected method.
There are also the SelectedIndices and SelectedItems collections but if you use these you would have to "fill in the gaps" yourself to figure out what isn't selected.
Alan.
|
|
|
|
|
The problem is your use of MultiSimple in the Listbox . The selected index is always the first one selected so if 1 is selected it always sets label1 visible and label2 not visible. Change the selection mode to One and you will see the difference. You will need to check all the selected items rather than just the index to be able to switch all labels correctly.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
HI Denis
try this,
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBox1.Items.Add("item 1");
listBox1.Items.Add("item 2");
listBox1.Items.Add("item 3");
listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged);
this.listBox1_SelectedIndexChanged(this, new EventArgs());
}
public void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Visible = (listBox1.SelectedItems.Contains("item 1"));
label2.Visible = (listBox1.SelectedItems.Contains("item 2"));
label3.Visible = (listBox1.SelectedItems.Contains("item 3"));
}
Best regard,
Nilesh Raval
|
|
|
|
|
Thank you Nilesh and also Alan and Richard.
Nilesh, you pointed me in the right direction! Thanks for the explicit code. -.SelectedItems.Contains is exactly what did the job.
|
|
|
|
|
Always welcome
|
|
|
|
|
Respected Sir,
I am new in web base application using c# & back end sql 2005 , I am create report file in crystal 10
please help me.
strFileNm = 'RpItemLst";
strFileNmWithPath = Server.MapPath(strFileNm + ".rpt");
RepDoc.Load(strFileNmWithPath);
===========below error============
Server Error in '/FactoryProduction' Application.
--------------------------------------------------------------------------------
Unsupported Operation. A document processed by the JRC engine cannot be opened in the C++ stack.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: Unsupported Operation. A document processed by the JRC engine cannot be opened in the C++ stack.
Source Error:
Line 157: //RepDoc.Load(strFileNmWithPath, OpenReportMethod.OpenReportByTempCopy);
Line 158: // RepDoc.Load("d:/sanadi/factoryproduction/RpItemLst.rpt");
Line 159: RepDoc.Load(strFileNmWithPath.ToString());
Line 160: CrystalReportViewer1.ReportSource = RepDoc;
Line 161: CrystalReportViewer1.DataBind();
Source File: d:\sanadi\FactoryProduction\RepItem.aspx.cs Line: 159
Stack Trace:
[COMException (0x80041811): Unsupported Operation. A document processed by the JRC engine cannot be opened in the C++ stack.]
CrystalDecisions.ReportAppServer.ClientDoc.ReportClientDocumentClass.Open(Object& DocumentPath, Int32 Options) +0
CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.Open(Object& DocumentPath, Int32 Options) +144
CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.EnsureDocumentIsOpened() +549
[CrystalReportsException: Load report failed.]
CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.EnsureDocumentIsOpened() +650
CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String filename, OpenReportMethod openMethod, Int16 parentJob) +1823
CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String filename) +186
RepItem.BtnPrint_Click(Object sender, EventArgs e) in d:\sanadi\FactoryProduction\RepItem.aspx.cs:159
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +112
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +36
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5563
|
|
|
|