|
The Problem:
I'm running C# and VB.NET projects from sourcesafe, with four developers working on the projects at any given time. The majority of any file references such as .DLLs and .SNK files are done via relative file paths i.e. ..\..\DataAccessLayer.snk.
In some cases, this relative approach doesn't work for some PCs that the developers use. Instead they need to use: \VMR\DAL\DataAccessLayer.snk
OK, you still with me? Good good. Now here's the final straw. We now have a project where neither of these file paths are allowing the project to compile. Instead it needs an explicit path name including the drive letter:
Assembly: AssemblyKeyFile("E:\VMR\DAL\DataAccessLayer.snk")
Unfortunately, I cannot impose that every developer keeps their source code on the same drive letter on their machines. The projects must support being installed onto various drive letters.
Firstly I cannot understand why a file path will work correctly on one machine and not another - and I have ensured that all the files etc. are in place as they should be.
So, unless there's some dumb user option I'm missing here, does anyone know why .NET behaves differently like this? Can I make it work 100% of the time without specifying a drive letter?
|
|
|
|
|
Martin Cross wrote:
So, unless there's some dumb user option I'm missing here, does anyone know why .NET behaves differently like this? Can I make it work 100% of the time without specifying a drive letter?
Just a thought, but why not always map to the UNC path (this way it's the same for every developer), who cares what drive letter any of your developers map to a network share, that could always change per developer as you are noting. In this case, there is even an article on CP to help with UNC paths: Network Shares and UNC paths[^].
P.S. - I'm sure Heath will respond to this eventually, I give him an hour or two.
-Nick Parker
DeveloperNotes.com
|
|
|
|
|
Network shares aren't the solution. A lot of us grab the latest version onto laptops and work from home using disconnected checkouts (dangerous I know).
So, am I not the only one where the file paths are a bit iffy then?
|
|
|
|
|
Simple: don't use files. Instead of using the AssemblyKeyFileAttribute use the AssemblyKeyNameAttribute . Import the key pair into a key container using sn -i KeyFile.snk MyCompany and then specify "MyCompany" (or whatever, so long as it matches) as the sole parameter to the latter attribute's constructor. You only need to do this once.
The only thing that isn't documented is whether the key container must exist as a machine container or a user container. It probably doesn't matter, but just a heads-up.
For a brief description, see my article: Using XML Digital Signatures for Application Licensing[^]. The articles not about your problem, but the solution is discussed a little (about key containers, that is).
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Good grief man! That's beautiful.
Thanks < bows down as he backs away slowly >
|
|
|
|
|
I use right mouse button to open next form in overridden OnMouseDown() method in overridden DataGrid (standard DataGrid works ok). Before this, automatic menu (copy, paste etc.) is opened - while creating new form. How to avoid it? Only OnKey...() has Handled property - but OnKey isn't fired.
-or-
How to add my item to automatic menu (copy, paste etc.)?
Thx in advance.
Hi,
AW
|
|
|
|
|
I'm not sure I quite follow, but if you want to change the default context menu, this is a bit tricky and not always possible. Instead, you could create your own ContextMenu (drag one from the Toolbox and design it like any other menu) and assign that to the DataGrid.ContextMenu property. That will completely replace the default context menu, but for things like Cut, Copy, and Paste, it's not hard to reproduce that functionality.
You can get the current cell from DataGrid.CurrentCell then cut or copy that text, or replace or append the text with your own paste handler.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
It's right. But I thought, that someone could solve this problem in simpler way. Thx.
Hi,
AW
|
|
|
|
|
Not everything you need is exposed in .NET because the framework would be huge! This isn't a hard solution, either.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
I have been sitting with a blob issue for the last day or so now. I am inserting a < 8k blob (image) into my MSSQL database from a OpenDialog Box, which I then from the database try and display in a PictureBox.
This is not working, purely becuase no matter what I do I keep on getting a "System Error" which makes no sense... I stream the image in and stream it out... into the picturebox. Anyone have any thoughts? Help?
Stitch
|
|
|
|
|
I got this working... thanx
|
|
|
|
|
i had wrote a set of class's for sending serialized objects over the net using sockets not to long ago..it worked perfectly then. I wrote a few programs (chat/file sharing) using the classes and they also worked perfectly. Just tonight i went back to use it agian with some new idea's and i have noticed i cant get my sockets to listen all of a sudden. i traced the error down to when the socket calls BeginAccept (the listening socket which is already done doing the setup to be in the listening state). I dont know if this is a code problem because i know for sure i havent touched the code when i used it, i just used the compiled dll's.I tryed uninstalling my old fire wall to see if thats the problem *zone alarm* but it didnt seem to fix it. The sending portion seems to work but the error only lies when i try to call begin accept intialy, This happens so when a connection does come in it is ready to accept it.here is the code with the error.
<br />
IPEndPoint ipe = new IPEndPoint(GetMachineIPAddress(),39888);<br />
MainListener= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);<br />
MainListener.Bind(ipe);<br />
MainListener.Listen(300);<br />
Thread.Sleep(10);<br />
MainListener.BeginAccept(new AsyncCallback(MainListenerBeginAccept),MainListener); <br />
if anyone wants to see the full code i would send it...its large and uses compression/serializing/encryption/ect/bla bla bla.
thanks alot for your help with this.
Jesse M
The Code Project Is Your Friend...
|
|
|
|
|
do you call EndAccept in your AcyncCallBack method? Something like this:
private void MainListenerBeginAccept(IAsyncResult asyncresult)
{
Socket s = (Socket)ar.AsyncState;
Socket s2 = s.EndAccept(ar);
}
Note I haven't tried it out, so it may or may not work. If you like I can have a look at your MainListenerBeginAccept method.
Ronny Andersson
|
|
|
|
|
yeah i do....here is the method i use. try running the code in junction with this and see if it works...
private void MainListenerBeginAccept(IAsyncResult e)
{
try
{
//MessageBox.Show("Acception connection");
Socket main = (Socket)e.AsyncState;
Socket secondary = main.EndAccept(e);
if(secondary!=null)
{
StateObject tr = new StateObject();
//MessageBox.Show(secondary.Available.ToString()+" ava");
tr.buffer = new byte[bufferSize];
tr.MainSocket = main;
tr.socket = secondary;
//
//Console.WriteLine("Beging To Accept");
//
SocketsConnected.Add(secondary);
//
//secondary.BeginReceive(tr.buffer,0,tr.buffer.Length,SocketFlags.None,new AsyncCallback(PendingConnectionReveive),tr);
}
MainListener.BeginAccept(new AsyncCallback(MainListenerBeginAccept),MainListener);
}
catch(System.ObjectDisposedException){}
catch(Exception ex)
{
OnError(this,ex);
}
}
The Code Project Is Your Friend...
|
|
|
|
|
I wrote a small test prog this morning just for fun. It is a very primitive
and small webserver it only sends a greeting back to the webbrowser.
Try it out locally on your machine with a webbrowser, then try it out
with between two machines. Try changing the port from 80 to something else
(I marked the line in red bold in the code) and try calling it again
if it doesn't work I agree with you it might be a firewall problem.
I've only got one PC at home so I cannot test it between two PCs.
God Luck
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TestSocket
{
class MiniWebServer
{
public static void OnAcceptConnection(IAsyncResult ar)
{
Socket serverSock = (Socket)ar.AsyncState;
Socket clientSocket = serverSock.EndAccept(ar);
try
{
serverSock.BeginAccept(new AsyncCallback(MiniWebServer.OnAcceptConnection),serverSock);
ClientStateObject cso = new ClientStateObject();
cso.worksocket = clientSocket;
clientSocket.BeginReceive(cso.buffer, 0, 256, SocketFlags.None,
new AsyncCallback(MiniWebServer.OnDataReceived), cso);
}
catch(Exception e)
{
serverSock.Close();
Console.WriteLine(e.ToString());
}
}
public static void OnDataReceived(IAsyncResult ar)
{
ClientStateObject cso = (ClientStateObject)ar.AsyncState;
try
{
int read = cso.worksocket.EndReceive(ar);
Console.WriteLine(Encoding.ASCII.GetString(cso.buffer,0,read).ToString());
if(read == 256)
{
cso.worksocket.BeginReceive(cso.buffer,0,256,SocketFlags.None,
new AsyncCallback(MiniWebServer.OnDataReceived), cso);
}
else
{
cso.buffer = Encoding.ASCII.GetBytes("<html><body>Hello from the MiniWebServer</body></html>");
cso.worksocket.BeginSend(cso.buffer, 0, cso.buffer.Length, SocketFlags.None,
new AsyncCallback(OnDataSent), cso);
}
}
catch(Exception e)
{
cso.worksocket.Close();
Console.WriteLine(e.ToString());
}
}
public static void OnDataSent(IAsyncResult ar)
{
ClientStateObject cso = (ClientStateObject)ar.AsyncState;
try
{
int sent = cso.worksocket.EndSend(ar);
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
cso.worksocket.Close();
}
}
[STAThread]
static void Main(string[] args)
{
Socket serverSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
<code>IPEndPoint endPoint = new IPEndPoint(0,80);</code>
serverSock.Bind(endPoint);
serverSock.Listen(1000);
serverSock.BeginAccept(new AsyncCallback(MiniWebServer.OnAcceptConnection),serverSock);
Console.ReadLine();
}
private class ClientStateObject
{
public Socket worksocket;
public byte[] buffer = new byte[256];
}
}
}
Ronny Andersson
www.codelive.com
|
|
|
|
|
i think it might be something my firewall because i cant even get a response out of this line of code
serverSock.BeginAccept(new AsyncCallback(MiniWebServer.OnAcceptConnection),serverSock);
it locks the program up every single time. i also noticed something strange...i like to seed my Random class with the current time..so i pass in this
Random rn = new Random((int)DateTime.Now.Ticks);
but every time i ran the code line above it would throw a stack overflow exception. I also tryed uninstalling / disabling the firewall and it didnt seem to do anything.Should i try reinstalling the framework or something ? any ideas ?
The Code Project Is Your Friend...
|
|
|
|
|
I found the problem. I was using this program called steganos internet anonm sounded intresting...makes your browser essentially hidden...but it must of be acting as a firewall also...blocking the framework form listening...my firewall was off...but even when it wasnt it said the my program was listening, so steganos must of be running between the too. Anyways thanks sooo much for your help i really apreciate it.
Jesse M.
The Code Project Is Your Friend...
|
|
|
|
|
Hi!
I have 2 different applications/assembly. The first one creates an object and serializes it to a textfile on disk.
The second one has the the exact same class (copied/pasted). It reads the file that is on disk and attempts to deserialize it and create a new object.
The process works fine if I serialize/deserialize in the first application, but it fails when I try to deserialize in the second application. Here's the exception:
Parse Error, no assembly associated with Xml key a1:http://schemas.microsoft.com/clr/nsassem/UI/UI%2C%20Version%3D1.0.1419.30011%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull AdonisConfigDisk
Although it is generally not a good idea to copy/paste code like I did (I should have 1 dll with the code I need), I am forced to do so for some reasons I won't go into right now.
Here's my code... Does anyone have an idea of what I'm doing wrong? How can I strip the assembly information from the serialized object?
<br />
public MemoryStream Serialize() {<br />
MemoryStream stream = New MemoryStream();<br />
SoapFormatter sf = New SoapFormatter(null, New StreamingContext(StreamingContextStates.All));<br />
sf.Serialize(stream, this);<br />
stream.Seek(0, 0);<br />
return stream;<br />
}<br />
<br />
public AdonisConfigDisk Deserialize(MemoryStream ms) {<br />
SoapFormatter sf = New SoapFormatter(null, New StreamingContext(StreamingCOntextStates.All));<br />
return DirectCast(sf.Deserialize(ms), AdonisConfigDisk);<br />
}<br />
Thanks!
Carl
|
|
|
|
|
The problem is that when you serialize an object, its Type is saved so that it can be deserialized to the proper object type later. In your error, that should now be clear. A Type includes the namespace, class name, assembly name, culture, version, and public key tokens. So, you can deserialize an object from another assembly...unless that assembly has the other assembly loaded!
When the object is being deserialized in the first assembly, the type references a type in that assembly so it's not a problem. When the other assembly tries to do it, the assembly in which the Type is defined may not be loaded. To make sure it is, get the current AppDomain in your second assembly (the one having problems) and call AppDomain.Current.Load (several overloads, see MSDN docs for details). This should work okay then.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Heath,
Thanks for your answer. However, it does not answer my question since I am not distributing the first assembly with the second. Both objects are the exact same, though (copy/paste).
Is there a way to "force" the deserialization even if the originating assembly is different?
Thank you!
Carl
|
|
|
|
|
If you can't include the assembly that has the type definition for the object you want to deserialize, you're either have to modify the string/binary data to change the assembly name (very dangerous!) or have a common library that defines that type that both assemblies you mentioned reference. The latter method would be much preferred.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
If I can't find a solution, I'm scared I will have to change the SOAP data in code... not very elegant but if it does the trick...
|
|
|
|
|
Again, I gave a solution that doesn't require changing SOAP: create a new library that contains the Type in question and use the Type out of that library in both assemblies that you mentioned earlier. That way both previously mentioned assemblies are independent of each other but share a common Type which both can serialize(/deserialize). This is an easy solution.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|
|
Heath,
Thanks for your replies! I finally managed to make it work by reflecting all the properties of my class into a dataset and exporting the dataset to xml. This is powerful enough for my needs.
I have encapsulated everything pretty well and it works like a charm now!
Thanks again!
Carl
|
|
|
|
|
So now you take the most inefficient method for serializing an object? Seriously, it's not a hard solution and this is a typically problem that modular programming is meant to solve. Just put the Type in a different assembly that both the first and second assemblies reference. This is a proper solution and what libraries are meant to do.
You can do it the way you want, but it's terribly inefficient.
-----BEGIN GEEK CODE BLOCK-----
Version: 3.21
GCS/G/MU d- s: a- C++++ UL@ P++(+++) L+(--) E--- W+++ N++ o+ K? w++++ O- M(+) V? PS-- PE Y++ PGP++ t++@ 5 X+++ R+@ tv+ b(-)>b++ DI++++ D+ G e++>+++ h---* r+++ y+++
-----END GEEK CODE BLOCK-----
|
|
|
|