|
Disadvantage for this strategy is that user must have a network connection which is always connected.
|
|
|
|
|
or at a site that blocks it (corporate firewalls etc)
|
|
|
|
|
Or they wireshark the "it's ok, run" response from the server, redirect the server domain to localhost, and then run the program forever using a fake server.
Or they'll just remove that check from the program, which is probably a lot simpler.
|
|
|
|
|
Or share the ID amongst several installations.
|
|
|
|
|
|
Better way is something like writing a hidden entry in registry or somewhere else.Keep updating the time at some events.Check whether the user is tampering with system Date , if he is doing some trick like this, expire the appln.Else run it for 30 days.
|
|
|
|
|
This isn't a better way, just another way. It also isn't secure, it is possible to download free registry watchers to see what is being changed. Checking whether the system date has changed is a problem too, as this can be done via the BIOS.
For .net apps there is no 100% way to secure against tampering, the best you can hope for is to stop the majority of users.
|
|
|
|
|
It's not worth the trouble. Just write the first version of the application, give it away for free, and see whether or not anyone likes it. If it becomes popular, maybe see about adding such things for version two. If not, at least you didn't waste your time.
|
|
|
|
|
I would write a registry value somewhere non-obvious on first use of the application with an encoded timestamp in it. You could also write an opaquely-named file into a system folder but since UAC it is not a given that you will be allowed to do that.
Any check of this kind you put on your application, particularly if it's written in .Net, will be pretty easy to find and remove, so don't put a lot of effort into it. But this kind of simple check is sufficient to tell people you'd rather they paid, and to protect the app from the vast majority of lazy users.
That said, you should strongly consider releasing software for free these days. Payware stands a good chance of turning people away, and the goodwill and potential future work you get from a quality free tool may well be worth more than the limited number of sales you'll get. And there's no need to try to protect free stuff.
|
|
|
|
|
hello guys... I have these two forms say From1 and Form2. Now I have some controls on Form1 and a datagrid on Form2. When I select a record from grid on Form2, I want this record to be shown on Form1.
Now I have got the data and saved it in the class - say DataClass.
DataClass data = new DataClass();
data.Id = Id;
data.Name = Name
. . .
But the problem is: how would I know user clicked the Select button or Close button, on Form2. Of course I wanna show data only when user clicks Select button. How can I do this? thnx
|
|
|
|
|
Have you opened Form2 using ShowDialog() ? If you have, just check the result for DialogResult.OK which equates to clicking the OK button. Then all you need to is retrieve the data from a property that you have exposed in Form2 that contains the data.
BTW - please give your forms meaningful names; there is nothing worse than having to maintain a project where everything has default names because it means you have to open everything just to find a particular form.
Hmm, I'm not sure why you were voted 1. I have balanced the vote out somewhat.
|
|
|
|
|
Actually it does not have the button OK, it has the button Select. So I dont know how your solution us going to map here. Any guidance in this regard will be appreciated.
I actually have meaningful names for my forms but to keep the question simple, I said them Form1 and Form2
|
|
|
|
|
It doesn't matter what the text says - all you need to do is set its DialogResult to OK.
|
|
|
|
|
In teclick event of the grid , create a new instance of form1 with an overloaded constructor of Form1.make DataClass as the parameter , then Show form from there.Done
|
|
|
|
|
So now he has two form1 instances running. I don't think that's the effect he's after.
|
|
|
|
|
There are two ways to do this, either by public/internal properties in Form2 or passing an instance of a custom class derived from EventArgs . Either will require some kind of signalling to Form1 that the data is ready.
As previously mentioned, if Form1 shows Form2 via ShowDialog() then you can expose a property in Form2, set the DialogResult of Form2 to DialogResult.OK and check for that as a result of the ShowDialog() call, accessing the property.
This same procedure can also be done by subscribing to Form2 s FormClosing event, although the dialog result is a better alternative as you have information relating to the success/failure of user interaction.
Alternatively, Form2 can raise a custom event subscribed to by Form1 . If using this method (the one I prefer) then you can pass a custom event args class instance along with the event that contains only the relevant data - nice and clean and no need to expose properties in Form2 to the whole world.
|
|
|
|
|
Yes , He can write a custom event.
|
|
|
|
|
This type of question: communication of data or events between two forms, is among the most commonly asked and answered type of question on QA in CP.
The critical piece of information to have, imho, in considering a solution is to know under what circumstances Form1 and Form2 (to use your form names) are created:
1. Keeping a run-time created reference: if Form1 creates Form2, or Form2 creates Form1: at the moment of creating it: the Form that creates has a reference to the other Form it has created.
That reference can be stored, and, then, all public properties (and methods, or anything else that's public) can be accessed by the creating Form.
In terms of the question of knowing when Form2 is closed: if Form1 creates Form2: at the moment its created and assigned to some variable in Form1: you can immediately subscribe to Form2's Closing or Closed events, and add an EventHandler defined in Form1.
Here's a code example that demonstrates both the above. First, this is implemented in Form2:
public DataGridView Form2DataGridView { get; set; }
private void Form2_Load(object sender, EventArgs e)
{
Form2DataGridView = dataGridView1;
} And, then, this is implemented in Form1:
private Form2 NewForm2
private void Form1_Load(object sender, EventArgs e)
{
NewForm2 = new Form2();
NewForm2.Closed += new EventHandler(NewForm2_Closed);
NewForm2.Form2DataGridView.SelectionChanged += new EventHandler(Form2DataGridView_SelectionChanged);
}
private void NewForm2_Closed(object sender, EventArgs e)
{
}
public void Form2DataGridView_SelectionChanged(object sender, EventArgs e)
{
} 1.a. The special case of using 'ShowDialog' for presentation of a Form is a special case of this: imho, nothing in the OP suggests 'ShowDialog' is being used. But, you have some good answers here, now, based on the assumption you use 'ShowDialog.' But, please note that you can create one, or both Forms, once, and keep a reference ... if one Form creates the other ... just as described above. Just re-use the reference to the instance of the Form in the ShowDialog mode.
1.b. The special case where both instances of Form1 and Form2 are created by some other entity: well, you can adapt what's suggested in points #1~2. ... edit ... This also is the case, imho, where you may explore the use of Interfaces to pass instances of Forms that implement the Interface cast to the Interface so you effectively limit what is exposed by the passed object. S. A. Kryukov often advocates this method in his QA answers: for example:[^]. ... edit ...
2. Injection: This usually means that one Form has a "vacant" public property, and another Form, when creating the second form with the property sets the value of the public property.
So, Form1 could have a public property of type DataGridView, and in Form2's Load event, Form2 could set the value of that property to the instance's DataGridView: but look at what is implied by that: Form2 must have access to the instance of Form1 ! To me this is "dog wag tail" implemenation: where this makes sense is if Form1 contains the DataGridView, and Form1 creates Form2, and Form2 needs access to the DataGridView on Form1. Then, this is easy because Form1 has access to the instance of Form2 at the moment it creates it.
2.a. I have to admit I have a strong bias against the idea of injecting a reference to a whole Class, or Form, into another Form or Class because I believe this is a violation of the principle of "separation of concerns."
Does Form1 really need access to everything public in Form2 ? If the answer is "yes," then I'd go for code as shown in the example above. But, if the answer is "no," then I'd modify Form1 code as shown above:
private DataGridView F2DataGridView;
private void Form1_Load(object sender, EventArgs e)
{
Form2 NewForm2 = new Form2();
NewForm2.Closed += new EventHandler(NewForm2_Closed);
F2DataGridView = NewForm2.Form2DataGridView;
F2DataGridView .SelectionChanged += new EventHandler(F2DataGridView _SelectionChanged);
}
private void NewForm2_Closed(object sender, EventArgs e)
{
}
public void F2DataGridView _SelectionChanged(object sender, EventArgs e)
{
} The difference in code may seem trivial: but, this implementation means that the only "exposed" object in Form2's instance within Form1's instance is the DataGridView on Form2, because the variable NewForm2 exists only in the scope of Form1's Load EventHandler.
2. Use of some "external" class to expose objects to other classes: You can create a public static class that maintains public Properties which can be set in each Form's 'Load, or 'Shown, EventHandlers, and then are visible to any Form in the same NameSpace. You could even set EventHandlers within that static class.
3. Raising events: This is probably the strategy most appropriate for the scenario you have described, particularly since it enables multiple subscribers to consumers (creators and users) of the instance(s) of Form2.
I've omitted code examples for #2~3, believing they are easy to find here on CP, within articles, tip/tricks, and QA, but if you have further questions, just ask.
"For no man lives in the external truth among salts and acids, but in the warm, phantasmagoric chamber of his brain, with the painted windows and the storied wall." Robert Louis Stevenson
modified 14-Dec-11 6:42am.
|
|
|
|
|
For any sort of complex application, both forms should be looking at some non-UI data model. So all Form2 should have to 'pass back' to Form1 is a selected index or an identifier for the model object that corresponds to the selected row.
Without knowing what the UI context of these two forms is (does Form2 spawn Form1 as an editor? are both forms top level forms? etc) it's hard to be more detailed than that. But the key point is that the data grid on Form2 should be a view on an IList<YourDataModelClass> (well, possibly, a BindingList or a BindingSource on a List) and the various controls on Form1 should be a view on the properties of a YourDataModelClass. You can achieve this with data binding or manually setting properties, and you'll probably want either the model class or a view-model to implement change notification (INotifyPropertyChanged) so that when you update things from Form1, Form2 also refreshes its view. If you're using WPF then you can just use Binding attributes in the XAML.
As Bill says this is a pretty common question in Q&A so you might want to search there and have a look at some of the recommended answers.
|
|
|
|
|
the relevant code
public static explicit operator ExcelWorksheet(Worksheet worksheet)
{
return new ExcelWorksheet(worksheet, 1,1);
}
public static explicit operator Worksheet(ExcelWorksheet worksheet)
{
return worksheet._worksheet;
}
...I'm trying to introduce a cast from the Interop.Excel.Worksheet to our Biz.Custom.ExcelWorksheet so that I can prep the COM proxy outside of the existing process, and allow an explicit cast from a valid COM Worksheet to be accepted as the custom's structurally subtyped property.
I researched the error and found out that this did not make the prioritization list to be removed from C#4 but could not find a workaround.
Does anyone have the proper incantation that will allow me to cast from the COM object to my custom?
Being required to convert these to "FromWorksheet" and "ToWorksheet" methods seems *completely* asinine.
"I need build Skynet. Plz send code"
modified 13-Dec-11 10:57am.
|
|
|
|
|
This is by design, as shown by this quote from the C# spec: "User-defined conversions are not allowed to convert from or to interface-types. In particular, this restriction ensures that no user-defined transformations occur when converting to an interface-type, and that a conversion to an interface-type succeeds only if the object being converted actually implements the specified interface-type". (source[^]). I don't really understand why you can't cast from an interface, but there you have it.
Having something that looks like a cast that actually switches to a completely different COM service is probably a bad thing anyway, though. When the conversion is so simple I recommend you just use 'new ExcelWorksheet(...)' and 'worksheet._worksheet' inline (well okay that last one should probably use a read property not the field directly).
|
|
|
|
|
Hello,
I am writing a project which sends SQL query to server, it runs it and returns back to client the results using streaming.
The flow is sending query,clientIP and port the client is going to listen to using WCF. before sending the WCF, the client opens a listener on the chosen port, and waits for a networkStream from the server. this done in a seperate thread. meanwhile the client sends the WCF request (with query,client ip, client port) to server and it returns the results to the waiting client on the right port.
All this done in seperate thread so i can run several queries simultanesly from the same client. After i received the results i am trying to close the TcpListener and TcpClient opened in the client side (in the opened thread). But when the other thread running it throws exception: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCal.
If i don't close the listener and client it works fine.
So how can i close the TcpListener and TcpClient in the thread without causing problem to the second thread .
TcpListener and TcpClient are not static.
Code:
private void OpenListenerTask(int port,AutoResetEvent resetEvent)
{
try
{
NetworkStream getStream = StartListenerGetStream(port, resetEvent);
string localIp = Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
var networkReader = new Reader(getStream, localIp, _sendPort.Value, _query);
networkReader.Start();
}
catch (Exception e)
{
Console.WriteLine(e.GetBaseException().Message);
}
//close TcpClient & TcpListener after data/error received
_client.Close();
_listener.Stop();
}
private TcpClient _client;
private TcpListener _listener;
private NetworkStream StartListenerGetStream(int port,EventWaitHandle resetEvent)
{
var tcpListener = new TcpListener(port);
tcpListener.Start();
_listener = tcpListener;
//tcpListener.Server.Blocking = false;
resetEvent.Set();
var tcpClient = tcpListener.AcceptTcpClient();
_client = tcpClient;
return tcpClient.GetStream();
}
|
|
|
|
|
michaelgr1 wrote: i am trying to close the TcpListener and TcpClient opened in the client side
You can't close a TcpListener in the client. The client doesn't own nor have access to that.
|
|
|
|
|
yes,
but in my solution, probably i didn't explain it. The server sending the data and the client receives it. So the listener is opened in the client side
|
|
|
|
|
I take it that your listener has nothing to do with the terminology in socket communication?
Why not use sender and receiver? That takes away the uncertainty of what issue you are really facing.
Cheers, AT
Cogito ergo sum
|
|
|
|
|