|
Hello,
In the old C style, I could create a window whenever I desired.
Is there a wrapped way of creating windowses an child windowses in C# (not Forms or Controls), or I have to make lots of pInvokes?
I hope you understand...because is a rough world out there...
|
|
|
|
|
Do u mean that u want to launch another process?
<< >>
|
|
|
|
|
No.
A Window is a basic element for rendering graphics to it, it has it's own messsage queue.
Every Control in .Net is based on something like that.
Afther some researching I think I found a minimalist wrapper in System.Windows.Forms.NativeWindow
I hope you understand...because is a rough world out there...
|
|
|
|
|
Since FileSystemWatcher doesn't work over samba (not implemented for performance reasons), i've had to write my own class using the FindFirstChangeNotification(...) api call. It's a blocking call that doesn't return until a change is made in the targeted directory, so I'm running my watcher in it's own thread. The problem is that when I call watcherthread.Abort(), the thread doesn't die until after a change is made to the folder. How can I force the thread to stop waiting for the api call adn to shut down.
|
|
|
|
|
I bypassed my problem after looking more closely at the code, and realizing I could pass a fixed ammount of time to wait before having FindFirstChangeNotification() return a timeout.
|
|
|
|
|
Hi
I'm writing a small WebServer for as a project.
I have a class called Pack1 that contians some properties which I want to send to the client.
[Serializable]
public class Pack1 : ISerializable {
public float[] FloatArray1;
public float[] FloatArray2;
public Pack1(){
FloatArray1 = new float[10];
FloatArray2 = new float[10];
//
// Set Data to these arays.
//
}
public Pack1(SerializationInfo info, StreamingContext ctxt) {
FloatArray1 = (float[])info.GetValue("FloatArray1",typeof(float[]));
FloatArray2 = (float[])info.GetValue("FloatArray2",typeof(float[]));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) {
info.AddValue("FloatArray1",FloatArray1);
info.AddValue("FloatArray2",FloatArray2);
}
}
I use binary Serialization to for the process:
[WebMethod]
public byte[] Test_Func3(){
Pack1 P = new Pack1();
byte[] Buffer;
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(1024);
formatter.Serialize(stream,P);
Buffer = new byte[stream.Length];
stream.Seek(0,System.IO.SeekOrigin.Begin);
stream.Read(Buffer,0,Buffer.Length);
return Buffer;
}
And, I have a Binder class to with with Deserialize:
[Serializable]
public sealed class Pack1Binder : System.Runtime.Serialization.SerializationBinder {
public Pack1Binder(){
}
public override Type BindToType(string assemblyName, string typeName){
string[] typeInfo = typeName.Split('.');
string className = typeInfo[typeInfo.Length -1];
if (className.Equals("Pack1")) return typeof(Pack1);
else return Type.GetType(string.Format("{0}, {1}",typeName, assemblyName));
}
}
and a small helper:
[WebMethod]
public System.Runtime.Serialization.SerializationBinder GetSerializationBinder(){ System.Runtime.Serialization.SerializationBinder binder = new Pack1Binder();
return (System.Runtime.Serialization.SerializationBinder)binder;
}
Up until now everything is OK.
The problem is when I deserialize the data on the other side.
On the client Side I have:
Service1 Ser = new Service1();
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream(1024 * 16);
stream.Flush();
byte[] Buffer = Ser.Test_Func3(10);
stream.Seek(0,System.IO.SeekOrigin.Begin);
stream.Read(Buffer,0,Buffer.Length);
stream.Flush();
stream.Write(Buffer,0,Buffer.Length);
stream.Seek(0,System.IO.SeekOrigin.Begin);
System.Runtime.Serialization.SerializationBinder binder = Ser.GetSerializationBinder(); <-- ???
formatter.Binder = binder;
Pack1 PP = (Pack1)formatter.Deserialize(stream);
The problem here is that the method GetSerializationBinder does not return the same type as System.Runtime.Serialization.SerializationBinder. If I try moving Pack1Binder to the Client then I get a message stating "Pack1 isn't serializable".
I looked over the net for a couple of hours for a solution and only found various similar questions asking pretty much the same thing.
Anyone ?
Gilad.
|
|
|
|
|
I am using an installer project for my application. On the installation folder dialog, there are two radio buttons, "Install the app for 1. everyone or 2. just me".
How do I get rid of this option? If not possible, how do I make the default selection to be "everyone" instead of "just me"?
Thanks.
My articles and software tools
|
|
|
|
|
You can edit the built MSI file using Microsoft's Orca program. Orca comes with the Microsoft Windows Software Development Kit. Here's the link.
http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en[^]
(I know it's a huge download just to get 1 little program, but I don't know how else to get it.)
Once you've installed Orca, you can right click on your MSI file and choose "Edit with Orca".
From there it'll display all of the MSI's innards like a database. Select the Property table and then right click on the right pane (on any row) and then select Add Row. Set the property name to "ALLUSERS" and its value to "1". This will make your installer install for everyone by default.
Now, I've noticed that in the RadioButton table that there are two rows named FolderForm_AllUsers. I've never played with these options before, but it looks like this is where you want to experiment with changing the installers behavior.
I hope this helps. Let me know if it works out for you.
|
|
|
|
|
|
Joshua Quick wrote: Orca comes with the Microsoft Windows Software Development Kit.
I didn't notice it is for Windows Server 2003. We are still using Windows 2000. I will definitely try it when we move to Windows 2003. Thanks.
My articles and software tools
|
|
|
|
|
Xiangyang Liu wrote: I didn't notice it is for Windows Server 2003. We are still using Windows 2000. I will definitely try it when we move to Windows 2003. Thanks.
The version I'm using is just called "Microsoft Platform SDK February 2003", which works fine on my XP system. I tried to link to the version I was using on Microsoft's site and it pointed me to the Windows Server 2003 SDK page. It looks like the same thing. Its system requirements does say it supports Win2000.
However, it looks like someone at Microsoft has provided easy access to Orca via his blog. Try this...
http://blogs.msdn.com/astebner/archive/2004/07/12/180792.aspx[^]
|
|
|
|
|
That just means that the SDK supports Windows 2003 and below. It's not a requirement to have 2003 to use it.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Hi all,
I'm design a windows forms application and i'm having some problems structuring it. The application itself will block a computer until a person gives a username and a password, after that it hides itself and keeps a small icon on taskbar. Lots of things will be happening meanwhile, syncs and comms with server, forms popping-up, and timers firing. My question is, what of the following approaches is the best one:
1. A console application looping forever (how to loop forever? System.Threading.Timeout.Infinite is a good choice?), which launches a splash screen on start, and then launches all other windows as needed, and keeps a child thread for server lookup (for server-client clock syncs, pings for new relevent items on server, etc). Note that the application requires timers which would probably need to be in class hosting static main().
2. A windows forms application, being the main form the one who blocks the computer, this will be the one that when minimized keeps the icon on taskbar. All other forms will be controled by this form (note the main form will be minimized most of the time)
3. The splash screen itself will be the main form, which appears only on start and then hides itself controlling all the processes and forms of the application.
Thanks to all of you
Best regards
João Vilela
jpmv
|
|
|
|
|
I have 2 project in a solution and i have added correct references. When I compile it in Debug mode it works fine but I am not able to compile it in relese mode I am getting the error saying (Are you missing a using directive or an assembly reference?)
the assemply it's missing is namespace for my 2nd project which i know i have added a reference in 1st project.
Please any help or advice?
really appericiated
Thanks, cpp
|
|
|
|
|
Possibly it has to do with with where the assembly is outputted in release mode compile. Did you add the reference to the second assembly by referencing the dll, or by referencing the project?
Matt Newman
Even the very best tools in the hands of an idiot will produce something of little or no value. - Chris Meech on Idiots
|
|
|
|
|
try to set 2nd project in release mode also...
<< >>
|
|
|
|
|
I am trying to complie whole solution and it's giving me assembly not found error.
Thanks
|
|
|
|
|
When you created the Reference, did you select the .DLL file directly or did you reference the .DLL's Project? Yes, it makes a huge difference.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Hi all,
I have a problem I cannot solve by my own. The message is quite long, but I hope that someone is nice enough to read it and give me a hand.
The basic problem is that I cannot sent events over .Net remoting that has an event argument as a class I have created, but strings as arguments works just fine.
I have three projects: Server, Middle and Client.
Server going to generate events and pass them through .Net remoting to the client. The middle project contains the remoted object. It also contains a delegate that is used to define the events generated in the server. The server is remoting the class in the middle project through a TCP channel.
The connection class in the server is remoting the object:
<br />
private void OpenConnection()<br />
{<br />
BinaryClientFormatterSinkProvider clientProvider = null;<br />
BinaryServerFormatterSinkProvider serverProvider = <br />
new BinaryServerFormatterSinkProvider();<br />
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;<br />
<br />
IDictionary props = new Hashtable();<br />
props["port"] = 7889;<br />
props["typeFilterLevel"] = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;<br />
props["name"] = "StatusControl";<br />
<br />
TcpChannel chan = new TcpChannel(<br />
props,clientProvider,serverProvider); <br />
<br />
ChannelServices.RegisterChannel(chan);<br />
<br />
RemotingConfiguration.RegisterWellKnownServiceType(<br />
Type.GetType("ProductionStatusControl.DistributedStatusControl, ProductionStatusControl"),"IDistributedControl", WellKnownObjectMode.Singleton ); <br />
<br />
m_single = StatusSingletonConnection.GetInstance();<br />
<br />
System.Threading.ThreadStart ts = new System.Threading.ThreadStart( SendMessages );<br />
System.Threading.Thread t = new System.Threading.Thread( ts );<br />
t.IsBackground = true;<br />
t.Start();<br />
}<br />
The middle project has a delegate:
<br />
public delegate void ProductionStatusDelegate( StatusMessage message );<br />
, a class as event argument:
<br />
[Serializable]<br />
public class StatusMessage<br />
{<br />
<br />
private FloatingStorageEventType m_type;<br />
private string m_message;<br />
<br />
public StatusMessage( FloatingStorageEventType type, string message )<br />
{<br />
this.m_message = message;<br />
this.m_type = type;<br />
}<br />
<br />
public FloatingStorageEventType MessageType<br />
{<br />
get{return m_type;}<br />
}<br />
<br />
public string Message<br />
{<br />
get{return m_message;}<br />
}<br />
<br />
}<br />
and a event type enumerator:
<br />
[Serializable]<br />
public enum FloatingStorageEventType<br />
{<br />
StatusText,<br />
Error, <br />
Warning, <br />
StorageStart,<br />
StorageStop,<br />
ProductionStart,<br />
ProductionStop, <br />
}<br />
The client connects to the server and starts to monitor for events:
<br />
try<br />
{<br />
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();<br />
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();<br />
serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;<br />
<br />
IDictionary props = new Hashtable();<br />
<br />
props["port"] = 0;<br />
props["name"] = "StatusControl";<br />
props["typeFilterLevel"] = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;<br />
<br />
m_chan = new TcpChannel(props, clientProvider, serverProvider);<br />
<br />
ChannelServices.RegisterChannel(m_chan);<br />
<br />
m_dist = (ProductionStatusControl.IDistributedControl) Activator.GetObject(Type.GetType("ProductionStatusControl.IDistributedControl, ProductionStatusControl"), "tcp://127.0.0.1:7889/IDistributedControl");<br />
m_dist.OnProductionStatusChanged += new ProductionStatusControl.ProductionStatusDelegate(m_dist_OnProductionStatusChanged);<br />
}<br />
catch( Exception ex )<br />
{<br />
System.Windows.Forms.MessageBox.Show( ex.ToString() );<br />
}<br />
The problem is that an exception is thrown in the
<br />
m_dist.OnProductionStatusChanged += new ProductionStatusControl.ProductionStatusDelegate(m_dist_OnProductionStatusChanged);<br />
part of the code.
<br />
System.ArgumentException: Error binding to target method.<br />
<br />
Server stack trace: <br />
at System.Delegate.InternalCreate(Object target, String method, Boolean ignoreCase)<br />
at System.Delegate.CreateDelegate(Type type, Object target, String method)<br />
at System.DelegateSerializationHolder.GetDelegate(DelegateEntry de)<br />
at System.DelegateSerializationHolder.GetRealObject(StreamingContext context)<br />
at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)<br />
at System.Runtime.Serialization.ObjectManager.DoFixups()<br />
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, IMethodCallMessage methodCallMessage)<br />
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, IMethodCallMessage methodCallMessage)<br />
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.UnsafeDeserialize(Stream serializationStream, HeaderHandler handler)<br />
at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryRequestMessage(String objectUri, Stream inputStream, Boolean bStrictBinding, TypeFilterLevel securityLevel)<br />
at System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)<br />
<br />
Exception rethrown at [0]: <br />
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)<br />
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)<br />
at ProductionStatusControl.IDistributedControl.add_OnProductionStatusChanged(ProductionStatusDelegate value)<br />
at TAKAnalyzer.Form1.btnConnect_Click(Object sender, EventArgs e) in c:\vsprojects\csharp\takanalyzer\mainform.cs:line 242<br />
The exception dissaperes it I change the parameter in the delegate from EventMessage to string. The string is accepted but not the EventMessage. No exception is thrown in the server, only in the client.
Please advice, I am totally lost here.
Best Regards
Mikke
|
|
|
|
|
Events conceptually are not sound in any network protocol. I'm surprised there was even an attempt in .Net Remoting to support this. The exception you are seeing is somewhat indicitive of the general problem. I wish that future versions of .Net Remoting would throw a more accurate exception than ArgumentException you often see in this case.
Okay so what is the problem? Mechanically, it can't serialize the delegate and event cleanly across .Net Remoting. Seriously, how would .Net Remoting even begin to handle an delegates/events? Ignore the actual mechanical problems with serialization for a moment and look at the concept you are trying to do. Bare with my crude ascii art
+--------------------------------------------+ +-------------------+
+ Client + + Server +
+ + + +
+ ObjectA CallRemoteB() + ---------------->+ ObjectB Call() +
+ { + + { +
+ b.ValueChanged += ValueChangeDelegate(); + + DoSomeStuff(); +
+ b.Call(); + err??? <--------+ ValueChanged(); +
+ } + + } +
+--------------------------------------------- +-------------------+
Remember that the client and server are for all purposes are in two seperate application domains let alone two different processes let a lone two different machines. If you don't understand why marshalling events across seperate app domains is tricky then read on.
The client is making a call b.Call which is remoted and marshalled correctly over to the server. If you don't do anything fancy, it is going to be syncronous and therefore block and wait for the response from the server. Over on the server, it is going to do the ObjectB.Call method when it makes an attempt to do the event. Okay, how does the server contact the client?? If you can't come up with a good answer then you see why events are a problem in Remoting.
Neither application domain knows what state the other is in. Even if the client is making an asycronous remote call, the client would have to *stop* execution on whatever it is doing and do the event. The client side is either blocked waiting for a response or the client application is listening asycronous but off doing some other parts of the client application. In either event, the app domain is not in a state where it can handle the event.
Simply put, one app domain needs to make a call on an object in another app domain it simply has no reference too. Even if it did, there is no underlying infrastructure on its own to marshal such a call (what port on the client does the server actually open the connection on to start the soap transaction???). .Net Remoting is "client->server->client". The client app domain simply can't act as a server.
To support events in .Net Remoting is giagantic mess. If you really want event/delegates you are going to have to simulate this by using the hint in the last sentance of the last paragraph: You need a client/server in both app domains. At this point you need some heavy duty engineering and even then it doesn't guarentee the end result will work: consider the problem of crossing a firewall.
I would consider redoing the event/delegate structure of your system. Rearrange your event/delegates so they are in the same domains since they don't make sense in any other domain. Trying to marshal them across just doesn't work right nor should they really make any sense.
-- modified at 15:43 Thursday 27th October, 2005
|
|
|
|
|
Hi!
Thank you for you reply! I realize that what I was trying to do was not as easy or smart as I thought..
What puzzles me is that it works well if I use a delegate with only a string as a argument. Why does that work?? I cannot have a delegate with two strings as arguments, but one work. I tried to implement the ISerializable interface. That did not work either.
I can buy the thought of the events not working if the server cannot find the client, that is reasonable. But why does it work if the argument is a string??
Best Regards
Mikke
|
|
|
|
|
Consider what is happening when you "sign up" for the event. You need to send a message to the server object to add ClientObject.ClientFunction to the delegate list. Assuming ClientObject is a MarshalByRefObject , it can marshal "itself" across. It can also marshal strings across. So technically it will succeed in making the functional call across the .Net Remoting. The problem is that it is meaningless to the server app domain because of all of the stuff I meantioned before. All of the object references only work in the client domain and will "blow up" if used in server domain.
Oh yeah, I did mention a way to work around the limitation in .Net Remoting but it might not be clear without an example:
ObjectA CallRemoteB()
{
b.Call();
if(this.ValueChanged != null)
this.ValueChanged();
}
The event/delegate is now only in the client app domain so everything works.
|
|
|
|
|
I'm using VS2005 RC1.
I have a project file which has several applications inside it. These applications all need to use some of the same classes. I'd like to define these classes in one file that is shared among the applications, but defined in a separate namespace. The windows applications all are in separate namespaces as well.
I tried adding a new class to the project in a new solution folder in a new class file. I added a new new space to the file containing the classes, but to no avail. I could not figure out how to access the classes from the other namespaces in the applications.
Can someone explain the correct way to do this? Thanks.
|
|
|
|
|
set references
and all classes u want to share must be public
eg.
public class foo{}
Please pardon my weak English!
|
|
|
|
|
To access classes in say a class library you need all of the classes you are accessing to be public, and you need to add a reference to the library. If the library isn't in the solution you can add reference by dll, but if the library project is within the current working solution you can add reference by project. There is a references folder in the solution explorer which is were you can access the references dialog.
Matt Newman
Even the very best tools in the hands of an idiot will produce something of little or no value. - Chris Meech on Idiots
|
|
|
|
|