|
If you want it to be more random you could use your original idea but with a random number generator to determine which array to look at rather than just selecting the longest array. Another idea would be to put everything in a single array and just use the random number generator to give a random index into the array and if the item in the index is in a different family, you've got a hit otherwise get another index from the random number generator.
List<int> peopleUsed = new List<int>();
Random r = new Random();
int person1Index, person2Index;
person1Index = person2Index = 0;
while(peopleUsed.Count < people.Length)
{
if(!peopleUsed.Contains(person1Index))
{
do
{
person2Index = r.Next(0, people.Length);
}
while(peopleUsed.Contains(person2Index) && !peopleAreInSameFamily(person1Index, person2Index));
peopleUsed.AddRange(new int[] { person1Index, person2Index });
}
person1Index++;
}
Keep It Simple Stupid! (KISS)
|
|
|
|
|
the problem I worry about with that is if you don't start with the longest list, then you might end up at the end with only members of one family
|
|
|
|
|
I am able to open uncompressed TIF files using
Bitmap objImage = new Bitmap(ImagePath);
but when I try to read compressed tif (JTIF) it gives me error.
Is there any way I can convert compressed tif to uncompressed?
Thanks.
Niks
|
|
|
|
|
NAMhatre wrote: Is there any way I can convert compressed tif to uncompressed?
Not using anything dependant on GDI+, no. GDI and GDI+ do not support LZH compressed (read JPG) TIFF files. You'll have to use a third party library to handle those files or an external tool to convert the files to uncompressed TIFFs.
|
|
|
|
|
Dave Kreskowiak wrote: LZH compressed (read JPG) TIFF files
Ummmmm LZH is a lossless compression algorithm, JPEG uses a lossy algorithm.
Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots.
-- Robert Royall
|
|
|
|
|
Ummmmm, yep, you're right! I haven't had to think about that problem in about 2 years now. Man did I screw that up, and I typoed the compression type too (LZW, not H).
|
|
|
|
|
Thinking of GIFs? LZH is a real compression algo so the typo angle never occurred to me yesterday.
Today's lesson is brought to you by the word "niggardly". Remember kids, don't attribute to racism what can be explained by Scandinavian language roots.
-- Robert Royall
|
|
|
|
|
Hi,
following problem:
I have a main application which starts a new thread while loading to show a splash screen.
The new thread is started within a form-class called splash with a static start method.
The splash screen is showed by splash.ShowDialog() in its constructor.
All happens within this class. So in the main application I only have to call the static start method on the splash class, it starts the new thread and initializes the splash class ... that's it.
When the splash closes himself in a timer event with splash.close() the splash is closed but also the main application is minimized!
Althoug it appears behind the splash screen when it is loaded.
I only want to close that splash screen and let the rest as it is .
Is there an easy solution to handle this?
I don't want to give the splash class a reference to the main application!
Thanks for any help,
Daniel
|
|
|
|
|
Hey Daniel,
Have you tried:
Splash.Close();
Splash.Dispose();
Hope this helps. Let me know how it goes?
Regards,
J.t.
|
|
|
|
|
I've developed a desktop application in .net 3.0 C# that is to be deployed to several users. I want to prevent the application .exe from being taken and used on an unauthorized PC. Currently, I've added some registry keys in the install package. The application looks for the registry keys when it launches, if it doesn't see the keys, it doesn't launch. That's working but I want to make sure that's the best way to do it. What is the best way to do that?
Thanks!
|
|
|
|
|
This is quite tricky to do, and it largely depends on how much time/money you are prepared to spend getting it perfect.
At the extreme end there are companies like KeyLok[^] and SmartLock[^] offer products where they use hardware USB dongles to perform checks before the software will run, so you can only run the software if you have a properly licensed dongle in the PC.
On the other end, you can just add reg keys and check them when your app starts like you've done.
It depends also on your target user. A general home user isn't going to be able to figure out how to copy the correct reg keys to a new machine.
You could improve it a bit by collecting some hardware data, or OS serial number or something like that, combining it with a unique license number for the user hashing it and giving the user that as a serial number. That way if they tried to install it on a different PC, serial number would not match the one that the app would generate from hardware data.
Ultimately though, anything written in C# can be easily reverse engineered by a competent programmer so the best thing to do is price is fairly, market it well, keep in touch with your customers. Think of good incentives to buy the real thing, like support, physical disks, manuals, etc and just hope that in general, most people are honest enough to pay for it.
Simon
|
|
|
|
|
If there is only one if statement that does the check, it really doesn't matter whether you use system registry, usb dongle or computer hash. Every application written in .Net can be easily decompiled and it only takes putting ! in the if statement to make an application work on every computer. Obfuscators make it more difficult but not very much. Even application written in native c++ or vb can be easily cracked. In case it's assembler that does the cracking.
The fact that general users will not be able to make necessary registry manipulation does not mean anything as usually it's crackers you crack the program and not users. Users just download them from warez websites. Crackers on the other hand have much more knowledge than general users and use advanced tools for cracking.
What I suggest is that you put checks at different places in the program and not so obvious. Having a dll called license.dll will attract crackers. On the other hand you can put some code in license.dll which looks like license check but does nothing in reality.
Good luck!
P.S. Remember that it is very difficult to make an application that can not be cracked. The only thing you can and should do is make more difficult your program to crack and put reasonable price on it so that it really does not make sense to crack it.
|
|
|
|
|
I am having problem to delete a Managed C++ DLL that was used in a
pure C# DLL even in the following scenario.
1. Launch the application. This applicatio has its own default
applicaiton domain.
2. Create a new Application Domain.
3. Load the Pure C# DLL in the new applicaiton domain. This C# DLL uses
managed C++ DLL.
4. Create a Proxy object using CreateInstanceAndUnwrap for the wrapper
object which is a wrapper for the class used from the pure C# DLL.
This wrapper object is exported from a seperate DLL.
DLL Configuration:- Wrapper for C# DLL, C# DLL, Managed C++ DLL.
The wrapper C# is used so that the main C# will not be loaded into
the default application domain when creating a Proxy object using the
menthod CreateInstanceAndUnwrap. The application domain talks with
only the wrapper DLL. If we do not have wrapper class, then the main
C# DLL will also be loaded into the default application. The sideeffect
of this is that, even when the new application is unloaded, we will not
be able to delete the main C# DLL. Wrapper is just a call frowader to
the C# DLL class.
5. Give the class name exported from C# DLL to the wrapper object and ask
it to create an instance of the class. The wrapper class creates the
the class and initializes its membet to it, so that it can forward
call requests.
6. From the default application domain, call a method on the wrapper object.
This call on the wrapper object calls the method on the C# class. This
C# class uses a function exported from a managed C++ DLL.
7. After executing the methods, unload the new application domain.
8. Now try to delete C# DLL, Mananged C++ DLL.
I was able to delete C# DLL, but not MC++ DLL. After further investigation
I found that the Visual Studio "Output" window has the following two lines:-
'Application.exe': Loaded 'C:\DLL1\Debug\MCPP.dll', Symbols loaded.----> LOADING FIRST TIME
'Application.exe' (Managed): Loaded 'C:\DLL1\Debug\MCPP.dll', Symbols loaded. ----> LOADING SECOND TIME
When the method on C# class is getting executed, the output log file
contains the above two lines. The .NET framework is loading it twice.
Once as Native C++ DLL, second time as Managed DLL.
Does any one know how to delete the MC++ DLL.
|
|
|
|
|
chandrap wrote: 3. Load the Pure C# DLL in the new applicaiton domain. This C# DLL uses
managed C++ DLL.
Where is this done from? Shouldn't the wrapper be doing this in the
new appdomain?
chandrap wrote: I was able to delete C# DLL,
It seems to me you shouldn't be able to do that. I'm missing something.
Isn't the C# DLL loaded in both appdomains (in steps 3 and 5)?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes you are correct, the Step3 is done in in the new application domain. Not in the default domain. Step5 uses the Step3 loaded assembly reference in the new appDOmain, to create the C# object.
Since the C# DLL is only loaded in the new application domain, I was able to delete it.
|
|
|
|
|
Hi
After further investigation I found out that the default application domain is also loading the MC++ DLL even though I do not use it anywhere in the default application domain. The only place I use MC++ DLL is in the C#. The C# DLL gets unloaded when I unload the new application domain since it was loaded only in the new application domain. Why is the MC++ DLL getting loaded both in default and new application domain.
Thanks
Chandra
|
|
|
|
|
Thanks
Why do you do step 3, and how do you do it?
It seems to me, the wrapper should be doing step 3, but you don't have a
wrapper until step 5.
What I'm getting at here, is an early binding to the C++ DLL, possibly caused by
step 3, where the C++ DLL is getting inadvertently loaded in both domains...
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you for your reply.
I create Assembly Manager class inside the new application domain
appDomain->CreateInstanceAndUnwrap("Wrapper.dll", "AssemblyMgr")
Then ask the wrapper DLL to load.
After this step we create the class in step 5 using the following code.
Type testClassType = assembly.GetType(className);
CSharpClass = (CSharpClass)Activator.
CreateInstance(testClassType);
Step3 is done to have the assembly loaded once, step 5 is used to create different classes from the same assembly. We do this because we do not know the DLL name at the compile time.
|
|
|
|
|
Huh?
I thought the wrapper was in a separate DLL?
You need the C# DLL to be able to load the wrapper DLL which needs the C# DLL?
It still seems to me the wrapper should be doing the loading of the C# DLL, at which time
it can obtain the required class name.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
We use Managed C++ DLL to load the wrapper DLL which is C# DLL. This managed C++ DLL supplies the DLL name, class name to the wrapper DLL. The wrapper DLL loads the C# DLL. Creates the C# Class. The C# DLL uses another managed C++ DLL internally.
|
|
|
|
|
How many wrapper classes are there?
Which C++ DLL are you unable to delete, and which DLLs reference it and how?
The original appdomain shouldn't need anything besides the wrapper DLL.
Is the wrapper class derived from MarshalByRefObject?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am not able to delete the Managed C++ DLL referenced inside the C# DLL. I checked the loaded assembly list using GetAssemblies. Then I found out the the Managed C++ DLL used in C# DLL is also loaded in the default application domain even though I do not use it anywhere except the C# DLL.
|
|
|
|
|
We're going in circles now...
I still question your step 3:
3. Load the Pure C# DLL in the new applicaiton domain. This C# DLL uses
managed C++ DLL.
Seems to me that's the place it gets loaded into the "default" app domain.
Can you look at the loaded assembly list before and after step 3 to confirm?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thank you for your replies. I found the solution to my problem. The problem is because the Managed C++ DLL that has been used in C# DLL refers to native C++ DLLs that have already been loaded in the main application i.e. default application domain.
So when the managed C++ DLL is getting loaded via C# DLL, the framework instead of loading the native C++ DLL in the new applicaiton domain, uses the DLLs from the default application domain. This is causing the managed C++ DLL also to be loaded into the default application domain. Because of this reason I was not able to delete the managed C++ DLL.
|
|
|
|
|
Makes sense
Good job tracking it down and thanks for the update.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|