|
Simon,
Thanks very much for you help. If you have a second I have two questions:
1. Why is "this" in "this.Invalidate();" the Form and not the button?
2. I've never seen the "using(Graphics g = e.Graphics)" syntax. Don't you have to create a new Graphics(); ?
thanks again...
|
|
|
|
|
1. Because the line is being painted on the form, not the button. Invalidate invalidates a region of a window (controls are windows, too, BTW) and the next time a paint message (WM_PAINT ) is sent to the window the line is painted.
2. using compiles to the following:
Graphics g = e.Graphics;
try
{
}
finally
{
g.Dispose();
} The using block is documented in the C# Language specification.
As I said in my reply, though, do not dispose the Graphics object. You only dispose Graphics objects (and pretty much anything else, for that matter) that you create. Since your code did not create the Graphics object via Control.CreateGraphics , Graphics.FromImage , or several other methods you should not dispose it yourself. The default implementation will dispose of the Graphics it created (which is actually from Graphics.FromHdc internally) when the OnPaint method (and any event handlers attached to the Paint event) return.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
To rephrase Heath's response in more plain english:
1.
I'm basically telling the form that something has changed and it needs to redraw itself. In a way, it is like calling the Paint event.
2.
As per Heath's quick response, it is exactly the same as writing: Graphics g = e.Graphics;
Except that you are automatically handling the disposing of the object yourself. Whether this is correct or not is, in my opinion, secondary to getting the code written, by hey, it's new year's and I've had a bit to drink... Thanks for point ing that out, H.
Cheers,
Simon
sig :: "Don't try to be like Jackie. There is only one Jackie.... Study computers instead.", Jackie Chan on career choices.
article :: animation mechanics in SVG blog:: brokenkeyboards "Most of us are programmers, but a few use VB", Christian Graus
|
|
|
|
|
Before you say it's just your opinion, you may want to look at the IL for the Control.WndProc and Control.OnPaint methods. If you have experience with GDI the reason is obvious: the Graphics is the HDC for the control to paint in, and if you dispose of it before it is used again the control will not be painted right and - depending on the implementation - may cause an AV (access violation) exception.
As a general rule of thumb you only dispose what you've created.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks for all the help... here's what I have so far...
/////////
bool bPaintLine = false;
Pen p = new Pen(Color.Plum);
private void btnGraph_Click(object sender, System.EventArgs e)
{
bPaintLine = true;
this.Invalidate();
btnGraph.Visible = false;
}
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
if(bPaintLine)
{
Point pt1 = new Point(10, 0);
Point pt2 = new Point(10, 400);
for(int i = pt1.X; i <= 40;)
{
Graphics g = e.Graphics;
g.DrawLine(p, pt1, pt2);
pt1.X += 10;
pt2.X += 10;
}
}
}
PROBLEM: It draws the lines and indeed the button disappears - but then it hangs up and crashes if I try to close the Form.....
|
|
|
|
|
What are you trying to do?
It looks like you have an infinite loop, if we assume that you really didn't indend to end your for statement with a -- Nevertheless it looks like you intended this:
for(int i = pt1.X; i <= 40; )
{
...
}
Which doesn't seem to make any sense. Since i is never changed, it is an infinite loop.
Are you trying to draw one line or several lines? If several, you might want to change to a scheme where instead of using a boolean (bPaintLine), you maintain a collection of lines to draw. Whenever you want to draw a line, you add it to the collection. Your OnPaint() draws whatever lines are in the collection.
By the way, it is probably a CP bug that it interprets emoticons inside preformatted blocks.
Matt Gerrans
|
|
|
|
|
hi all here and happy new year
i have bringing out thes problim yesterday in vb.net thread but i don't have any suggestion
i wish if any body here could help me the problem was published as :
i have urgent problem i don't know what i must do to solve it
the project that i work on consist of server and client application
it represent real Time system
and have three connections
on the client sied the problem is that:
i have found that the CPU usage is 100% this isn't the usaual case of the client
first :when i watch the threads from control panal-->performance i found that one thread go up
and take most resource
i don't know how to catch this thread
second :i note that if i put any break point to stop the applecation then let it run again
the CPU usage go down to a good level
Aswanee
|
|
|
|
|
|
I was reviewing articles at CP for quickstarts and articles that would cover the ability to send email messages and attchments from a Windows C# program. I came across an article about SMTP Trace Listeners at http://www.codeproject.com/csharp/smtptracelistenerarticle.asp, but this article appears to deal with the System.Web.Mail namespace which is not available in a windows application.
Is what I am looking for presented at the MESSAGING segment provided at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpqstart/html/cpsmpnetsamples-howtodiagnostics.asp? Any suggestions on how to proceed with sending an email message and possible attachment either using an .htm/javascript file ON THE FLY (transparently) or a windows namespace using C#?
|
|
|
|
|
new_phoenix wrote:
I came across an article about SMTP Trace Listeners at http://www.codeproject.com/csharp/smtptracelistenerarticle.asp, but this article appears to deal with the System.Web.Mail namespace which is not available in a windows application.
Of course it is, but you need to add a reference to the System.Web.dll to your project, first.
Best regards
Dennis
|
|
|
|
|
Doh!!! Thanks, Dennis. I will give it a try. Appreciate the nudge in the right direction.
|
|
|
|
|
Keep in mind that will only work for Windows NT-based platforms. The System.Web.Mail classes use CDO to send mail, which is implemented by a small client library and by services like Microsoft Virtual SMTP Server (required to send mail for ASP.NET applications) and Microsoft Exchange (can also be used for ASP.NET applications, but is not required).
If you want to support all platforms on which the .NET Framework is supported, you need to send SMTP messages yourself. It's really not hard and is very similar to the HTTP protocol. See RFC 821[^] for the technical details, although you could click "Search comments" directly above this message board and search for my previous comments about this very question, such as how to resolve MX records for the SMTP server for a domain (so that you know which computer to actually connect to and send mail).
There are third-party libraries out there that are either cheap or free, too. The .NET Framework 2.0 beta also includes a "generic" implementation of SMTP that doesn't rely on CDO to send mail.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I will read the RFC 821 article that you had provided. It is my understanding from your comments that the System.Web.Mail namespace will only work on a Windows NT platform. I would like my application to work on any CLIENT computer from a standard windows form. For example, I am using only Windows 2000 Professional, and I am not certain that there are any services included providing even SMTP services.
There are several articles provided at codeproject.com. Could you kindly write an article, and itemize/clarify all the steps that are required to send an email message with attachments, describing this MX record in more detail, and for maximum portability? Also, what are the limits for this technology, operating systems, etc.
Would appreciate further elaboration...
|
|
|
|
|
new_phoenix wrote:
For example, I am using only Windows 2000 Professional, and I am not certain that there are any services included providing even SMTP services.
As I mentioned in my reply, if a client application is using SmtpMail the CDO client library is used. It's only when you're doing this within ASP.NET that a CDO server is required. If you know you'll only be running on Windows 2000 Pro or newer, then you don't really need to send SMTP messages yourself.
new_phoenix wrote:
Could you kindly write an article, and itemize/clarify all the steps that are required to send an email message with attachments, describing this MX record in more detail, and for maximum portability?
As I said in my last reply, click "Search comments" and search for SMTP. I've covered this more times than I'd like in the past. Searching is just part of research, which is just part of development.
I will write an article eventually but when I have more time, which is rare. SMTP is not a difficult protocol to implement, however. What my planned article is about has more to do with MIME and S/MIME than SMTP, though that will be covered. It could be a couple months before I release this.
Making SMTP portable is not a problem: it's a well-established protocol, and a protocol means that every implementation of the protocol must follow it. Making your code portable is simply a matter of looking at the bottom of the member documentation in the .NET Framework SDK and making sure it supports the platforms you require. For most of the .NET BCL (base class library) the members are supported on all Windows platforms.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Also, if you're looking for articles then you should search this site, first. Here's a URL for a search (using the textbox directly below the logo at the top of the page) limited to C# and .NET categories, simply searching for "SMTP". A few of these have good ratings, so view those first (within your scope; some may not apply):
http://www.codeproject.com/info/search.asp?cats=3&cats=5&searchkw=SMTP[^]
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I’m building a Dictation / Transcription program. I’ve got everything working however I would like to put a indicator on the form that will show when someone is dictating that it is recording their voice ( i.e. Like the simple Record Sound program in Windows that shows a real time amplitude graph). I believe this can be done using the Mixer API but there is just not enough documentation that I can find on this.
Is there a plug-in that I can purchase out there already made? Or perhaps some type of documentation to steer me in the right direction to create my own?
This project is being created in C# using DirectX 9 SDK
Any advice would be appreciated.
|
|
|
|
|
Have you looked at the Windows Multimedia[^] SDK? If you know how to P/Invoke native functions and declare structs and constants for proper marshaling it isn't too difficult (though the older APIs are a little more cumbersome to use). Read Consuming Unmanaged DLL Functions[^] and Marshaling Data with Platform Invoke[^] in the .NET Framework SDK for more information.
I threw together this simple example that shows how to handle callbacks for mixer devices. In a real-world scenario you'd want to enumerate the devices and allow the user to select one, or select a default one for them (typically 0). I also didn't take the time to check the Message.LParam property for the actual data, which you'd use to tell OnPaint what to draw for a level indicator. This should give you a pretty good start, however. Compile it and run it and start recording your voice. You should see messages being output to the console (compile with csc.exe /t:exe , not /t:winexe or you won't see console output).
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class Levels : Control
{
int mixerId = -1;
IntPtr hmx;
const int CALLBACK_WINDOW = 0x00010000;
const int MIXER_OBJECTF_MIXER = 0x0;
const int MM_MIXM_CONTROL_CHANGE = 0x03d1;
[DllImport("winmm.dll")]
[return: MarshalAs(UnmanagedType.U4)]
static extern int mixerOpen(out IntPtr phmx,
[MarshalAs(UnmanagedType.U4)] int uMxId,
IntPtr dwCallback, IntPtr dwInstance,
[MarshalAs(UnmanagedType.U4)] int fdwOpen);
[DllImport("winmm.dll")]
[return: MarshalAs(UnmanagedType.U4)]
static extern int mixerClose(IntPtr hmx);
public Levels()
{
SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.Selectable, false);
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if (hmx != IntPtr.Zero)
mixerClose(hmx);
if (mixerId >= 0)
{
int result = mixerOpen(out hmx, mixerId, Handle, IntPtr.Zero,
CALLBACK_WINDOW | MIXER_OBJECTF_MIXER);
if (result != 0) throw new Win32Exception(result);
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == MM_MIXM_CONTROL_CHANGE)
{
Console.WriteLine("{0}: Received a message.", DateTime.Now);
}
}
public int MixerId
{
get { return mixerId; }
set { mixerId = value; }
}
}
class Test : Form
{
static void Main()
{
Application.Run(new Test());
}
Test()
{
Levels c = new Levels();
Controls.Add(c);
c.Location = new Point(8, 8);
c.MixerId = 0;
}
} Hope this helps.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks this really helps alot.
|
|
|
|
|
Hi
I'm using c# in a game development project, can anyone point me to a cardinal splines tutorial with c# code that doesn't use the gdi, but uses managed directx?
Thanks very much
|
|
|
|
|
http://search.msn.com/results.aspx?q=DirectX+cardinal+splines[^]
Apply that to Managed DirectX using DirectDraw ro to build meshes in Direct3D. Because Managed DirectDraw is deprecated you may have to P/Invoke DirectX APIs in order to draw splines. This site has several good articles about encapsulating the native DirectX APIs with some downloads you may find useful.
BTW, .NET does not use GDI but GDI+. Doesn't matter much in terms of your problem, but it's still worth mentioning. GDI is used only in rare cases like to get device capabilities (a la GetDeviceCaps ). Everything in System.Drawing and its child namespaces uses GDI+, however.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hi
At present The program what it does is reads any xml schem afile and load data's automatically for each fields in a new xml file. (ie, fora field name "company name" datatype-string - ( values stored as john1, john2..etc up to 200)like that.
Now what I need is , to give a meaning full data.
Ie, I have another xml file with same field name " company name" with meaninful data'a upto 200 data's.
Now I want to insert the data's from that xml file( that field "company name" alone) into the new xml field (company name").
Transferring a single field data's into a new xml file .
PLEASE HELP ME TO DO THAT.
:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Xml;
using System.Xml.Schema;
namespace testdatagenerator
{
///
/// Summary description for Form1.
///
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox txtSchema;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox txtXml;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.DataGrid dataGrid1;
private System.Data.DataSet dataSet1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.txtSchema = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.txtXml = new System.Windows.Forms.TextBox();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.dataSet1 = new System.Data.DataSet();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.dataSet1)).BeginInit();
this.SuspendLayout();
//
// txtSchema
//
this.txtSchema.Location = new System.Drawing.Point(232, 24);
this.txtSchema.Name = "txtSchema";
this.txtSchema.Size = new System.Drawing.Size(368, 20);
this.txtSchema.TabIndex = 0;
this.txtSchema.Text = "";
//
// button1
//
this.button1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.button1.Location = new System.Drawing.Point(616, 24);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(64, 23);
this.button1.TabIndex = 1;
this.button1.Text = "Browse";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// txtXml
//
this.txtXml.Location = new System.Drawing.Point(232, 64);
this.txtXml.Name = "txtXml";
this.txtXml.Size = new System.Drawing.Size(368, 20);
this.txtXml.TabIndex = 2;
this.txtXml.Text = "";
//
// button2
//
this.button2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.button2.Location = new System.Drawing.Point(616, 64);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(64, 23);
this.button2.TabIndex = 3;
this.button2.Text = "Load";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.button3.Location = new System.Drawing.Point(696, 64);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(64, 23);
this.button3.TabIndex = 4;
this.button3.Text = "Save";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// dataGrid1
//
this.dataGrid1.DataMember = "";
this.dataGrid1.DataSource = this.dataSet1;
this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(0, 120);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(776, 320);
this.dataGrid1.TabIndex = 5;
//
// dataSet1
//
this.dataSet1.DataSetName = "NewDataSet";
this.dataSet1.Locale = new System.Globalization.CultureInfo("en-US");
//
// label1
//
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label1.Location = new System.Drawing.Point(32, 24);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(184, 23);
this.label1.TabIndex = 6;
this.label1.Text = "Enter the Xml Schema";
//
// label2
//
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
this.label2.Location = new System.Drawing.Point(32, 64);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(192, 23);
this.label2.TabIndex = 7;
this.label2.Text = "Enter the Xml file";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(808, 454);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.dataGrid1);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.txtXml);
this.Controls.Add(this.button1);
this.Controls.Add(this.txtSchema);
this.Name = "Form1";
this.Text = "TestDatagenerator";
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.dataSet1)).EndInit();
this.ResumeLayout(false);
}
#endregion
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
OpenFileDialog fdlg = new OpenFileDialog();
fdlg.Title = "select schema file" ;
fdlg.InitialDirectory = @"c:\CDEV\testdatagenerator" ;
fdlg.Filter = "schema files(*.xsd) |*.xsd| all files(*.*) | *.*";
fdlg.FilterIndex = 2 ;
fdlg.RestoreDirectory = true ;
if(fdlg.ShowDialog() == DialogResult.OK)
{
txtSchema.Text = fdlg.FileName ;
}
}
private void button2_Click(object sender, System.EventArgs e)
{
dataSet1.ReadXmlSchema(txtSchema.Text);
foreach (DataTable dTbl in dataSet1.Tables)
{
for(int j = 0; j <= 200; j++)
{
object[] oValues = new object[dTbl.Columns.Count];
int i = 0 ;
foreach (DataColumn dColmn in dTbl.Columns)
{
switch(dColmn.DataType.ToString())
{
case "System.String":
oValues[i] = (string) "Castle Hampers" + j;
break;
case "System.Int32":
oValues[i] = (int) 100 + j;
break;
case "System.DateTime":
oValues[i] = new DateTime(2004,01,30).AddDays(j * 1);
break;
case "System.Decimal":
oValues[i] = new Decimal(10000900.99) + j;
break;
case "System.Int16":
oValues[i] = (short) 32767 - j;
break;
case "System.Int64":
oValues[i] = (long) 400 - j;
break;
case "System.Double":
oValues[i] = (double) 888888 - j;
break;
case "System.Single":
oValues[i] = (float) 4.5f + j;
break;
}
i = i+1;
}
dTbl.Rows.Add(oValues);
}
}
}
private void button3_Click(object sender, System.EventArgs e)
{
dataSet1.WriteXml(txtXml.Text,XmlWriteMode.WriteSchema );
MessageBox.Show("Saved");
}
}
}
santhosh
|
|
|
|
|
I'm not sure I understand this or your previous post yesterday, but if I do understand you right you simply want to copy all the companies into a new XML file. Is that correct?
There's many ways you can do this. You could use an XslTransform to transform the one XML file to another without even loading the XML file into a DataSet . Using the right classes for the job is important. The DataSet class, for example, has a heck of a lot of overhead for just reading an XML file. Using the XmlDataDocument class is far better in terms of performance and functionality when dealing with the XML rather than the data itself.
For more information on XslTransform , read the documentation[^] for the class in the .NET Framework SDK.
If this is alread loaded into a DataSet , then get a reference to the DataTable that contains the company names and simply enumerate the DataTable.Rows . For each DataRow in DataTAble.Rows , get the company name field and either put it in a new DataTable using DataTable.NewRow , setting the column data, and adding the DataRow using DataTable.Rows.Add , or simply write out the data from the company name column into a file.
There's so many ways of doing this but you really need to read the .NET Framework SDK documentation for the classes to see what's possible.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hi
I wish you a Joyful and Happy New Year.
I am new to c# , so I dont know how to do.
ie,
My requirement exactly is :
Now My program reads a schema file( with field names name(string), salary(decimal)).
They are read and the values are inserted to the fields automatically.Like
(john1,john2,john3,..etc. for name)(2000, 2001,2002 , ..etc for salary).They are written into a xml file(say for instance salaryemp.xml).
this is what happens to my program.
Now what I have to do , I should be able to read another xml file( say for instance corporate.xml) which also has this name field with many original datas( like james, george, munna,..etc. ). So my program should read these values and fed(insert) into salary.xml file(only the name field should get altered with the values of corporate.xml). the salary field should remain the same.
pls help me to do that .
Just give me a coding help.
santhosh
|
|
|
|
|
Hi Everybody,
When I add a C# dll to a C# exe, using Add Reference. The "Copy Local" property of the dll is set to "True" for default.
Can any one give me info about adding the dll's to the exe and what property to be set and what are the pros and cons of the same.
Any article or link explaining the same would be very helpfull.
Thanx in advance.
saleem
|
|
|
|
|
First of all there's no such thing as a C# DLL or C# exe. The Common Language Infrastructure (CLI) of which the .NET Framework is Microsoft's implementation (Mono and Portable.NET are alternative CLI implementations) describes that managed languages are compiled to Intermediate Language, or IL. That's not to say the result from equivalent code in different languages is the same, but close (compilers perform optimizations and may include other features that other compilers don't have).
That being said, when working on a multi-project solution it's best if you use project references instead of assembly references. This creates project dependencies, so that changes in a dependent project will make sure it gets compiled first before compiling the target project. It also makes sure that your target project is up-to-date with the latest version of the assembly.
There are only three options for dependent assemblies: copy the assembly to the local obj and bin directories, install the assembly into the GAC, or use a runtime configuration file.
The first - copying the assembly locally - is best for development. You will undoubtably be changing your project often and the CLR needs to resolve your assembly. It will use the current directory, then a configuration file, then check the GAC (Global Assembly Cache). It does not use the PATH environment variables like native appliation loaders do, but you can set a separate DEVPATH for developmental purposes, but this is not recommended.
Installing the assembly into the GAC is only recommended for released assemblies, like third-party libraries you use or your own in-house libraries that have been released internally. For projects that change often this gets to be a real hastle and you need to reference the assembly to build anyway. The GAC is only used at runtime and referencing a GAC-only assembly (i.e., there's no assembly in a version directory, like there is in the %WINDIR%\Microsoft.NET\Framework\<Version> directory) in difficult because you can't use Windows Explorer (so not the Open or Save dialogs, either, so that you could browse for the assembly).
The third option requires that you update your configuration file and know about publisher policies, version redirection, codebase changes, etc. It's not worth it.
Note that "Copy Local" is for runtime purposes, as is everything about. The path of the assembly that you're referencing is still used to build against. If "Copy Local" is set to true, then the assembly is first copied but this is primarily for runtime. If the CLR can't resolve your dependent assembly an exception will be thrown and your application will not run.
For more information about how the CLR ("Runtime") resolves assemblies, read How the Runtime Locates Assemblies[^].
To learn about publisher policies and other runtime configuration settings, start by reading Redirecting Assembly Versions[^] along with the next few topics after it, including Specifying an Assembly's Location[^].
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|