|
|
#1 |
|
Member
Join Date: Jan 2003
Posts: 79
|
Copying single multibyte characters with StrCpy
I have this function that takes a string that is a directory path and tries to figure out what's the upper most directory that has to be created.
For example, if the user wants to install the app to: C:\Program Files\ABC\123 and ABC doesn't exist in Program Files, the function will return C:\Program Files\ABC, it makes it usefull for deleting all the directories that you've created upon uninstall. The function looks like: PHP Code:
PHP Code:
PHP Code:
Does anyone have any ideas of a better way to copy one character at a time that handles multibyte characters? Or is there a better way to iterate over the parent directories of a path? I'm using NSIS 2.01b if that helps. |
|
|
|
|
|
#2 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Use GetParent to get the C:\Program Files\ABC bit, then use GetFileName to get hold of ABC.
All functions are on the NSIS Archive -Stu |
|
|
|
|
|
#3 |
|
Member
Join Date: Jan 2003
Posts: 79
|
That has the same problem.
PHP Code:
|
|
|
|
|
|
#4 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Have you tried getting the latest CVS, because maybe new support for these characters have been added.
I know that it will be a lot of work converting to the new NSIS2b4 format, but it's worth it. -Stu |
|
|
|
|
|
#5 |
|
M.I.A.
[NSIS Dev, Mod] Join Date: Oct 2001
Location: Israel
Posts: 11,310
|
The latest CVS version won't help with this. But it does contain an example to what you're trying to do (folder stuff, not MBCS). You can find this example online, here.
To be to get one "real" character you should use CharNext with System.dll. BTW, why are you comparing it to a quoted space? NSIS FAQ | NSIS Home Page | Donate $ "I hear and I forget. I see and I remember. I do and I understand." -- Confucius |
|
|
|
|
|
#6 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
With the GetParent and GetFileName functions, just blank out the lines that compare the variable to "" that come below the single character seperation.
It won't matter whether or not the character is invalid ("") or not then. (All you want to look for is "\", so there is no need to check for "" which is usually the output got at the end of a string) -Stu |
|
|
|
|
|
#7 |
|
Member
Join Date: Jan 2003
Posts: 79
|
I'm not comparing anything to a quoted space. It's an empty string. ""
|
|
|
|
|
|
#8 |
|
Member
Join Date: Jan 2003
Posts: 79
|
So if i blank those lines, how does it know if it's reached the end of the string?
|
|
|
|
|
|
#9 |
|
M.I.A.
[NSIS Dev, Mod] Join Date: Oct 2001
Location: Israel
Posts: 11,310
|
Haha, I'm going blind
![]() Anyway, the only way you'd know what you're up against is by using CharNext or IsDBCSLeadByte. But you don't need either, just use the script I have attached, it's much more efficient. NSIS FAQ | NSIS Home Page | Donate $ "I hear and I forget. I see and I remember. I do and I understand." -- Confucius |
|
|
|
|
|
#10 |
|
Member
Join Date: Jan 2003
Posts: 79
|
Right, I see why that solution would work. There's a problem with it however, if the user had created an empty directory previously, then installed the application into that directory, the uninstall would delete the directory the user created beforehand even though it wasn't created by the application's installer.
This may or may not be the wish of the user. The safer route is to delete only the directories that the installer creates. |
|
|
|
|
|
#11 | |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Quote:
![]() -Stu |
|
|
|
|
|
|
#12 |
|
Member
Join Date: Jan 2003
Posts: 79
|
$INSTDIR isn't terminated with a \ character.
|
|
|
|
|
|
#13 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
?
If $INSTDIR is e.g. C:\quake2\dday, then it will see the "\" before "dday". $INSTDIR is a run-time variable, so changes to whatever the user has entered. -Stu |
|
|
|
|
|
#14 |
|
Member
Join Date: Jan 2003
Posts: 79
|
Right.
What about this example: C:\Program Files\ABC (C:\Program Files exists, ABC does not) It checks to C:\Program Files\ finds it exists. Keeps copying over characters. Copies A, then B, then C, then copies "" not "\" and just loops infinitely because we're not checking for the end of a string that's not terminated by "\". Doesn't work, does it? |
|
|
|
|
|
#15 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
I don't understand why you think it won't work.
It checks for "\", then when it is found (it will be) it gets straight out of the loop, gets ABC from the string, then exits the function. There is no way it will loop unless you're string has no "\" in it. -Stu |
|
|
|
|
|
#16 |
|
Member
Join Date: Jan 2003
Posts: 79
|
I know it won't work because I tested it. Take a look at the loop:
PHP Code:
|
|
|
|
|
|
#17 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
I am wondering now why you need the function...
Because, the $INSTDIR is created automatically anyway. If $INSTDIR is C:\progra~1\abc\123 then subdirs abc and 123 are created anyway. -Stu |
|
|
|
|
|
#18 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Code is wrong.
code: -Stu |
|
|
|
|
|
#19 |
|
Member
Join Date: Jan 2003
Posts: 79
|
Right. But if you read my previous posts you'll see I'm worried about the uninstall process.
RMDIR $INSTDIR only removes C:\progra~1\abc\123 and not C:\progra~1\abc. |
|
|
|
|
|
#20 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
There's a problem with what you want too...
What happens if the $INSTDIR is just C:\progra~1\abc? abc will be removed, then you will remove the next directory down which is C:\progra~1!!! -Stu |
|
|
|
|
|
#21 |
|
Member
Join Date: Jan 2003
Posts: 79
|
Are you that familiar with the NSIS code?
RMDIR removes the directory only if it's empty. RMDIR /R removes the directory recursively. In the previous code C:\Program Files\abc would be identified as the top level directory and stored in the registry. That would be the top most directory that would be removed, not C:\Program Files, not sure where you got the idea that the code would attempt to remove that directory. |
|
|
|
|
|
#22 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Sorry, missed that.
Ok. I will right a small function for this because I think that it would be useful. -Stu |
|
|
|
|
|
#23 |
|
M.I.A.
[NSIS Dev, Mod] Join Date: Oct 2001
Location: Israel
Posts: 11,310
|
There is a very simple solution to avoid comparing to "" and it's to simply append a back-slash to the end of the string.
As for deleting empty directories the user have created, unless you want to create the directories manually at install time and save in a log each directory created, that's what you've got. NSIS FAQ | NSIS Home Page | Donate $ "I hear and I forget. I see and I remember. I do and I understand." -- Confucius |
|
|
|
|
|
#24 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Try this out.
Usage: Push 2 ;check 2 last dirs Push $INSTDIR Call RemoveDirs code: -Stu |
|
|
|
|
|
#25 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Just tested it, and changed 1 thing - works fine.
Re-copy the script. I will put this on the archive. -Stu |
|
|
|
|
|
#26 |
|
Member
Join Date: Jan 2003
Posts: 79
|
How are you calling it?
|
|
|
|
|
|
#27 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
|
|
|
|
|
|
#28 |
|
Member
Join Date: Jan 2003
Posts: 79
|
That looks good. I'll give it a try.
However, how do you know how many directories are created? Would it involve iterating over $INSTDIR in SecCopyUI and create each directory piecemeal correct? Then we'd probably have to copy a character at a time, right? Which takes us back to the original problem. I have yet to try out NextChar, I'll post my findings when I am finished. Thanks! |
|
|
|
|
|
#29 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
Look at my script.
It bypasses the problem that we had before. By comparing the strlen with the minus (chop number) Therefore, if the strlen and chop number are equal, then it has got to the end of the string. If you want to find out how many subdirectories there are, use this: code: -Stu |
|
|
|
|
|
#30 |
|
Moderator
Join Date: Nov 2002
Location: Shropshire, England
Posts: 6,887
|
So you're code should look like this:
code: -Stu |
|
|
|
|
|
#31 |
|
M.I.A.
[NSIS Dev, Mod] Join Date: Oct 2001
Location: Israel
Posts: 11,310
|
tderouin, do the MBCS characters come right if you copy byte by byte? Afrow UK's code should help you test that.
NSIS FAQ | NSIS Home Page | Donate $ "I hear and I forget. I see and I remember. I do and I understand." -- Confucius |
|
|
|
|
|
#32 |
|
Member
Join Date: Jan 2003
Posts: 79
|
I'm just getting around to testing this now, SubdirsAmount doesn't actually record how many directories are going to be created. It should probably be changed to check to see if a directory exists, if it doesn't exist then increment the number of subdirs, if it doesn't exist don't increment but continue copying.
I'll play with it and post new code if I find a better way. Ex: SubdirsAmount C:\Documents and Settings\user\Start Menu\Programs\Product returns 6 but only one dir is being created, so in the uninstall log you see: rmdir C:\Documents and Settings\user\Start Menu\Programs\Product rmdir C:\Documents and Settings\user\Start Menu\Programs rmdir C:\Documents and Settings\user\Start Menu rmdir C:\Documents and Settings\user rmdir C:\Documents and Settings rmdir C: Which wouldn't look to pleasant to the user. |
|
|
|
|
|
#33 |
|
Member
Join Date: Jan 2003
Posts: 79
|
I found this was a good way for finding the numbeof subdirs that had to be created:
PHP Code:
PHP Code:
PHP Code:
|
|
|
|
|
|
#34 |
|
M.I.A.
[NSIS Dev, Mod] Join Date: Oct 2001
Location: Israel
Posts: 11,310
|
What about the MBCS characters? Do they come out right?
NSIS FAQ | NSIS Home Page | Donate $ "I hear and I forget. I see and I remember. I do and I understand." -- Confucius |
|
|
|
|
|
#35 |
|
Member
Join Date: Jan 2003
Posts: 79
|
Yes, this seems to work for multibyte characters.
|
|
|
|
|
|
#36 |
|
NSIS MUI Dev
Join Date: Nov 2001
Posts: 3,718
|
I have updated the GetParent function, so it should support MBCS now. Can you please test this one? Thanks
![]() code: |
|
|
|
![]() |
|
|||||||
| Thread Tools | Search this Thread |
| Display Modes | |
|
|