|
-
Mar 23rd, 2013, 04:26 PM
#13
Re: Open several files using Command
 Originally Posted by Fenrir
I've never used GUID, so excuse me if I ask for stupid questions. I'd like to create a new one via code, using the CreateGUID from your link like this:
Code:
If CreateMutexW(lpName:=StrPtr(CreateGUID()) Then
won't each new instance create a new univocal GUID for itself?
If it's so, I think the condition will always fail. I should always use the same GUID (declaring it as Const), but doing like this, there's the riks another app uses my same GUID? Well, what are the advantages of this practice if all my assumptions were true?
You are mostly correct. The GUID should indeed be declared as a constant. You will need to generate a new GUID for every single-instance app that you create. That way, when any of your apps create a named Mutex, they won't clash with each other or with any other apps. GUIDs are designed to be very unique so there's virtually no chance that another app generated the same GUID as yours.
 Originally Posted by Fenrir
And what if user doesn't use relative paths? I'd have (for example) a variable that contains this:
newCommand$ = """C:\Program files\my_exe_dir"" ""C:\documents and settings\user\desktop\file.ext"""
Now, if I try to execute the Open statment:
Code:
Open newCommand$ For Input As #1
won't I should receive an error??
Here is Raymond's argument for including the current directory:
If you make a single-instance program, and somebody runs a second copy of the program and passes a command line, the most common way of handling this is to hand the command line to the first copy of the program and let the first copy deal with it. When you do this, don't forget about the current directory.
If somebody passes a relative path to the second copy of the program, that relative path needs to be resolved against the current directory of the second program. I've seen programs that fail to take this into account. Instead, they pass the command line to the first copy of the program, and the first copy resolves the relatives paths against its current directory.
Allow me to give a concrete example.
C:\Directory1> start LitWare file1.lit
... runs LitWare with the file C:\Directory1\file1.lit ...
C:\Directory1> cd ..\Directory2
C:\Directory2> start LitWare file2.lit
What you expect to happen is that LitWare opens the file C:\Directory2\file2.lit, since the relative path file2.lit should be resolved against the current directory, C:\Directory2. Unfortunately, I see some programs try to open the file C:\Directory1\file2.lit since they passed the command line to the first copy, and the first copy then resolved the relative path file2.lit against the current directory of the first copy, namely C:\Directory1.
Result: "File not found error."
Moral of the story: Be mindful of the current directory when parsing the command line. You can either have the second copy parse the command line (and resolve the relative paths against its own current directory), or you can pass the current directory to the first copy (and resolve the relative paths against that directory). Either works. What doesn't work is passing the relative paths to the first copy and having the first copy resolve it against its own current directory.
I will leave the command line parsing implementation up to you. You can probably find examples of that here.
 Originally Posted by Fenrir
Don't you think that if also my application has to keep always open a file to read/write the hWnd of the first instance, this may slow or damage the HDD?
The locked file that will be created is only about 10 Bytes or so. Since your app reads from the disk while starting up, creating a file at the same time poses no problem for the HDD. Similarly, when your app shuts down, you probably persist some settings to disk. Deleting the locked file at around the same time should not have any detrimental effects to the HDD. Note that the Registry is composed of several files on the disk.
 Originally Posted by Fenrir
These are cases at the borders of reality O_O A more concrete case maybe you find another program that uses the same Caption of your own. But, reading the article, I discovered a possible solution: the loop goes on until (hPrevWnd = 0) Or ((hPrevWnd <> 0) And (DataRecived = False)), where DataReceived is a variable that changes to True when the SendMessage will successfully processed by the first instance.
You might think that such cases are rare, but they do happen and when it does, your app had better be prepared.
But the point here is that FindWindow is unreliable. You'll probably be better off implementing your own window searching algorithm. You could use SendMessageTimeout for instance, so your app can avoid being blocked by a hung thread.
 Originally Posted by Fenrir
I was reading that a ClassName is assigned for registered applications only (even though I don't know what it means).
See About Window Classes.
 Originally Posted by Fenrir
Are you sure that will it work?
You can always revert to vbNullString if it fails. However, if you want to reduce the chances of FindWindow finding another window that has the same caption as yours, then you should include the classname.
On Local Error Resume Next: If Not Empty Is Nothing Then Do While Null: ReDim i(True To False) As Currency: Loop: Else Debug.Assert CCur(CLng(CInt(CBool(False Imp True Xor False Eqv True)))): Stop: On Local Error GoTo 0
Declare Sub CrashVB Lib "msvbvm60" (Optional DontPassMe As Any)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|