|
Thanks for all help!
Im not realy understand how it works, but i will have to look it up.
Anyway, we will try to set Transfer.dll to version 1.0.0.0 and then recompile the controls once and for all. After this we hope that if we make a change in the Transfer.dll we will not have to update al the controls. Yes we will not see what version is the newest, but we can always se on the date when the file is created.
//Jimmy
|
|
|
|
|
What's not to understand? Besides being documented in practically every way you can think of in the .NET Framework SDK, the concept is simple: you have an application and an application configuration file (App.exe and App.exe.config). They go into the same directory. Some settings you can use your application such as the appSettings section via ConfigurationSettings.AppSettings . Some the CLR uses when loading your application, such as assembly binding. Put the XML like I showed you before in that .config file and when the CLR tries to load an older assembly that another assembly references, your .config redirects it to a newer version. So long as the assemblies are compatible, there would be no problems. This is all outlined rather clearly in the SDK. If you don't get it after reading that and my numerous attempts to explain it, then I'll guess you'll have to recompile your client and server applications every time and deploy them in their entirety.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have understod that.
But this simes only applying to a compiled program(exe file)
I need it to applay even when i start upp the project in Visual Studio.net. I have created a file as you explaned(app.exe.config) and it have got the right name at compilation. But if i close the Project, and copy a new dll file over the old(and ofcours change the version nr in app.exe.config) and then open the project, some controls will be lost due to version errors. I guess that this config file onlye applayes to the compiled file?
And this i dont find any information about, but in general i have problem to understand some of the msdn articles so maby its not that strange.
Anyway, i understand your frustations.
//Jimmy
|
|
|
|
|
No, I said create a file in VS.NET called app.config. VS.NET will automatically rename and copy this file to the target directory with the proper name.
You don't need to do this in VS.NET, though. It's a simple text file - an XML file to be exact - with a .config extension, just like the Web.config file. VS.NET will not benefit from this .config file (at least not until VS.NET 2005) nor will it help you construct it. You need to understand the simple concepts provided in the links I gave you originally. All you're doing is telling the Common Language Runtime (CLR) to bind to a different version of an assembly when a particular version (or version range, which can be used in the oldVersion attribute) is required.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yes.. i have understand so far, its a regular file with exe.config on the end, and that i can add it by my self or by using Visual Studio. But i diddent know that is only applays to the exe file.
I dont see the point on just adding the new dll file to the exe file, not in our case. there will not be any code in our client that can handle the new funktions in the dll file.
I dont know if we understand eachother.
If i take it again.
We got a client and a server. The Client contains alot of "WindowsControlLibrarys"(own made controls) and this controls includes this Transfer.dll(Collections of classes) that countains all the Classes that we sends between the client and server.
The Transfer.dll file is located in C:\Project\Client\bin\Debug and all the "WindowsControlLibrarys"(own made controls) is including this file at this location(C:\Project\Client\bin\Debug), even the client is using this file itself.
So we hoped that if we compile the "WindowsControlLibrarys" that points at the same Transfer.dll loacated in C:\Project\Client\bin\Debug and includes it to the client, then if we need to update the Transfer.dll we only Close the project, copy the new one over the old one in C:\Project\Client\bin\Debug and then starts up the project again, and by that we dont need to recompile the "WindowsControlLibrarys", but this dident work becourse the "WindowsControlLibrarys" states what version that is included, and tryes to copy this to the C:\Project\Client\bin\Debug directory, witch it cant do becourse there already is a new version.
Then i think of : The "WindowsControlLibrarys" dont need to know of the update in the Transfer.dll, only the client need to know, so if we change the version on the transfer to 1.0.0.0 and recompiles the "WindowsControlLibrarys" with this Transfer.dll then in next update of the Transfer.dll it will not complain becource the new version have the same version(nr 1.0.0.0), and the client will be abled to use the funktions, and maby the own made controls will not aomplain about versions.
This is not a good way to solve this on, becource we will not know what version we are using, insted we will have to look at the date of the file creation.
Proberly this is totaly wrong way to do things, but maby it could work.
I have ready the links, but i cant get it to work in the project, and it simes like it is not supose to do that eather?
//Jimmy
|
|
|
|
|
Thank You.
Sorry For Bad English.
|
|
|
|
|
Not knowing English very well is no excuse for a such a long subject. Next time, please use a brief subject and explain your subject in your post's body.
There are many installers available. The setup and deployment projects in VS.NET are a joke, so forget using them. You might instead take a look at Wise Solutions[^] or InstallShield[^].
Being also an installer author (using the Windows Installer technology), let me tell you that having 59 objects from which the user is to select is not a good idea. Would you like to go through 59 options and decide which to install? I seriously doubt it. I know that I and many others would not.
It's your product: make it easy for the user to install. Combine those 59 options into fewer options with a larger scope or break them down into a tree structure (like Windows Installer features can do).
Think about Microsoft Office. There's probably about that many features in an Professional installation, but they combine them under Word, Excel, Outlook, etc. If users want to be more specific about which options to install under those, they can drill down and select more specific features.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Dear, Sir
Thank You very much for your reply.
My goal is I want to create installer that have tree structure like Microsoft Office Installer.
Is setup and deployment projects in VS.NET can create an installer like Microsoft Office installer?
If it can, how to?
Thank Again.
|
|
|
|
|
No, because the VS.NET installer project does not allow you to specify features or even have a feature dialog. Instead, use Wise for Windows Installer[^] or InstallShield for Windows Installer[^]. I recommend Wise. I've worked with both since Windows Installer 1.0 and each's 1.0 versions and Wise has always been completely extensible (giving you access to all the advanced features of MSI through a table UI) and not nearly as bloated or expensive as InstallShield.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
How can I create a listbox with each item presented by a combobox?
Thanks in advance.
|
|
|
|
|
One idea would be to use owner drawing and in your handler for the DrawItem event (or, if you extend ListBox - which is a better idea for enscapsulation - override OnDrawItem ) and use the DrawItemEventArgs.Bounds to position an instance of a ComboBox tied to each item. The trick is to make sure that the ComboBox instances are created and disposed when an object is added or removed from the ListBox . The best way is to extend ListBox.ObjectCollection with your own collection class and override ListBox.CreateItemCollection so that you return an instance of your derivative class.
To make sure that Windows messages are properly dispatched, you may need to add each instance of the ComboBox to the ListBox.Controls collection property. Never tried this, so I'm really not sure. All the owner-drawn ListBox es I've written and have seen simply draw the items.
See the documentation for the ListBox.DrawMode property in the .NET Framework SDK for more information on owner drawing with a ListBox .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
I am attempting to produce some code that performs fairly simple LDAP queries, unfortunately I can't seem to get this running. The code I currently have is :
private void GetProps()
{
int LDAP_PORT = 636;
string LDAP_IP = "111.222.333.444";
string ID_CODE = "X246555";
string ldapPath = string.Format("LDAP://{0}:{1}/o=testo/ou=Services", LDAP_IP, LDAP_PORT);
string filter = string.Format("(&(IdCode={0})(sname=urn:this:that:something:or:other))", ID_CODE);
DirectoryEntry de = new DirectoryEntry(ldapPath);
using (DirectorySearcher searcher = new DirectorySearcher())
{
searcher.SearchRoot = de;
searcher.Filter = filter;
searcher.SearchScope = SearchScope.Subtree;
searcher.PropertiesToLoad.Add("prop1");
searcher.PropertiesToLoad.Add("prop2");
searcher.Sort = new SortOption("prop1", SortDirection.Ascending);
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult result in results)
{
Console.WriteLine(result.Properties["prop1"]);
Console.WriteLine(result.Properties["prop2"]);
}
}
}
This code is born of various docs found on the net and also within MSDN, when run it fails with this error :
Unhandled Exception: System.Runtime.InteropServices.COMException (0x8007203A): The server is not operational
The thing is I know that the server is running and configured correctly as I can perform the same query from the same machine via OpenLDAP and this returns exactly as expected.
If anybody could help me out here I would truely appreciate it.
post.mode = postmodes.signature;
SELECT everything FROM everywhere WHERE something = something_else;
> 1 Row Returned
> 42
|
|
|
|
|
On what exactly is the exception thrown? I'm guessing searcher.FindAll() .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
You guessed correctly
post.mode = postmodes.signature;
SELECT everything FROM everywhere WHERE something = something_else;
> 1 Row Returned
> 42
|
|
|
|
|
Specify at least AuthenticationTypes.ServerBind for DirectoryEntry.AuthenticationType . According to the docs:If your ADsPath includes a server name, specify this flag when using the LDAP provider. Do not use this flag for paths that include a domain name or for serverless paths. Specifying a server name without also specifying this flag results in unnecessary network traffic. Your ADsPath includes the server name, so you must bind to the server. If you don't require write access, you might also specify AuthenticationTypes.ReadonlyServer (the AuthenticationTypes enumeration is attribute with the FlagsAttribute so you can OR themn together using | ).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks alot for the suggestions, unfortunately I had already tried the various flags with no result.
Now the rest of this post is in "thinking out loud" mode, but if anybody has a clue feel free to join in
The LDAP server I was attempting to connect to is beyond my control, so while playing around I have setup my own ldap server (OpenLdap)
Now if I run the server using the default LDAP port I can connect and retrieve data using the following paths :
string ldapPath = "LDAP://10.139.42.89:389/dc=domain,dc=com";
string ldapPath = "LDAP://10.139.42.89/dc=domain,dc=com";
I can also use the openLdap LdapSearch tool to retrieve data aswell
If I start the server using any other port, say 9898, when I attempt to retrieve data using the following path it fails :
string ldapPath = "LDAP://10.139.42.89:9898/dc=domain,dc=com";
This fails on FindAll() with "The Server is not operational"
But I can still perform searches to that port using the openLdap ldapSearch tool
So I thought that maybe the .NET framework was ignoring the port and always going to the default (389) but if I run the server on the default port and use the following connection string :
string ldapPath = "LDAP://10.139.42.89:9898/dc=domain,dc=com";
It still fails
Every single document I look at advises that ldap connection paths should be formatted in the way the ones above are, which I assume is correct as I can make connections to the default port either by specifying or not - but it doesnt explain why I cannot connect to non default ports.
post.mode = postmodes.signature;
SELECT everything FROM everywhere WHERE something = something_else;
> 1 Row Returned
> 42
|
|
|
|
|
Of course the last example is going to fail; the LDAP server isn't running on port 9898.
The questions you have to start asking yourself are about authentication more than likely. For example, when you use the OpenLDAP tools to search the directory, are you specifying any credentials or other options besides the server to bind to and the query?
Also, regardless of whether or not you're having problems, you'll still need those flags I mentioned before to bind to the server if it's in your ADsPath.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Although the authentication flags are important, I am fairly certain they are not the cause of this problem (I am currently using AuthenticationTypes.ServerBind | AuthenticationTypes.ReadonlyServer)
While testing the connection strings detail above the only changes that are made are :
- changing the port in the declaration of "ldapPath".
- changing the port that the LDAP server is listening on.
Whilst on the default port (389) everything works as it should, connections can be made and I can perform queries which return exactly what I would expect them to.
According to ldap docs changing the listen port is just that, nothing else changes so the way the C# client authenticates shouldnt need to change either.
I have also downloaded a few different ldap browsers, all of these work regardless of the port the server is listening on, and I am 101% certain I am using the correct connection details (if I wasnt I wouldnt be able to connect on the default port). There is something odd afoot here, and I will be damned if its going to beat me.
post.mode = postmodes.signature;
SELECT everything FROM everywhere WHERE something = something_else;
> 1 Row Returned
> 42
|
|
|
|
|
And as I asked before, with all these clients, what are you specifying for credentials (if any) and other options? Something is obviously different.
Also make sure that you have the latest service packs and other updates for your system. Since the Directory Services in .NET uses COM interop with native libraries, you want to make sure that those libraries don't have any bugs.
A good test would be to find a client with which to test that uses the same COM servers on your Windows system. I believe that there are some in the Windows Server Resource Kit (for 2000 and 20003). The problem may be with the COM servers, although I highly doubt it since you're not the only one who would try this.
Have you read over all the AuthenticationTypes enum member documentation? There may be other stuff you have to specify. The clients you've been trying would use necessary binding flags as well, you just probably wouldn't know about it or be able to control them (or at least all of them).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hello,
I'm trying to write my own custom toolbar from scratch.
Now I've a problem: I created a class named coolToolBarButton which contains information about the button. Those buttons are grouped into a coolToolBarButtonCollection-Class.
I tried to add buttons to the toolbar via the designer, but it doesn't work. I clicked on the porperty field and the "coolToolBarButton Collection Editor" appeared. I was able to add some buttons, but then I clicked on the OK-Button and the buttons weren't added to the collection!
What's wrong?
Here's the code:
public class coolToolBarButton
{
private Image m_Image;
[DefaultValue(null),
System.ComponentModel.RefreshProperties(RefreshProperties.Repaint)]
public Image Image
{
get { return m_Image; }
set
{
m_Image = value;
}
}
}
public class coolToolBarButtonCollection : CollectionBase
{
public int Add(coolToolBarButton Button)
{
return List.Add(Button);
}
public void Insert(int index,coolToolBarButton Button)
{
List.Insert(index, Button);
}
public void Remove(coolToolBarButton Button)
{
List.Remove(Button);
}
public bool Contains(coolToolBarButton Button)
{
return List.Contains(Button);
}
public int IndexOf(coolToolBarButton Button)
{
return List.IndexOf(Button);
}
public void CopyTo(coolToolBarButton[] array, int index)
{
List.CopyTo(array, index);
}
public coolToolBarButton this[int index]
{
get { return (coolToolBarButton)List[index]; }
set { List[index] = value; }
}
}
///
/// Summary description for coolToolBar
///
public class coolToolBar : System.Windows.Forms.Control
{
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
private coolToolBarButtonCollection m_ButtonCollection;
public coolToolBarButtonCollection Buttons
{
get { return m_ButtonCollection; }
set
{
m_ButtonCollection = value;
}
}
.......
|
|
|
|
|
When you change the images collection, you have to Invalidate the control which will force it to repaint. I got extremely frustrated with the same problem!
|
|
|
|
|
Do you mean they don't show up on the toolbar, or that they aren't serialized to code? If you mean the latter case, you must attribute your collection property with DesignerSerializationVisibility(DesignerSerializatioVisibility.Content) (uses the DesignerSerializationVisibilityAttribute ) so that it serializes the collection to your source file. You can also override this behavior by attributing your toolbar class with a custom designer using the DesignerAttribute .
See Enhancing Design-Time Support[^] in the .NET Framework SDK for more information on the .NET component model and design-time capabilities.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
It works now! Very good!
But there's another problem: I placed my custom toolbar on the form and added some buttons. If I remove the toolbar, the single buttons don't get removed from the code!
|
|
|
|
|
This is my code:
[DesignTimeVisible(false)]
public class coolToolBarButton : Component
{
private Image m_Image;
[DefaultValue(null),
System.ComponentModel.RefreshProperties(RefreshProperties.Repaint)]
public Image Image
{
get { return m_Image; }
set
{
m_Image = value;
}
}
}
public class coolToolBarButtonCollection : CollectionBase
{
public int Add(coolToolBarButton Button)
{
return List.Add(Button);
}
public void AddRange(coolToolBarButton[] Buttons)
{
for(int i=0;i<buttons.length;++i)
list.add(buttons[i]);
="" }=""
="" public="" void="" insert(int="" index,cooltoolbarbutton="" button)
="" {
="" list.insert(index,="" button);
="" }
="" remove(cooltoolbarbutton="" list.remove(button);
="" bool="" contains(cooltoolbarbutton="" return="" list.contains(button);
="" int="" indexof(cooltoolbarbutton="" list.indexof(button);
="" copyto(cooltoolbarbutton[]="" array,="" index)
="" list.copyto(array,="" index);
="" cooltoolbarbutton="" this[int="" index]
="" get="" {="" (cooltoolbarbutton)list[index];="" set="" list[index]="value;" }
="" <summary="">
/// Summary description for coolToolBar
///
public class coolToolBar : System.Windows.Forms.Control
{
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
private coolToolBarButtonCollection m_ButtonCollection;
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public coolToolBarButtonCollection Buttons
{
get { return m_ButtonCollection; }
set
{
m_ButtonCollection = value;
}
}
public coolToolBar()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();
m_ButtonCollection=new coolToolBarButtonCollection();
SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.StandardDoubleClick |
ControlStyles.UserMouse |
ControlStyles.StandardClick |
ControlStyles.SupportsTransparentBackColor,
true);
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
#region Component Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
protected override void OnPaint(PaintEventArgs pe)
{
// TODO: Add custom paint code here
// Calling the base class OnPaint
base.OnPaint(pe);
}
}
|
|
|
|
|