Tuesday, January 15, 2008

The registry

Just finished reading the comments in my 'Big changes' post; there are some interesting comments about the registry in there.

Could the registry be replaced? Sure, in software, pretty much any change is possible.
In practice though...If you were to replace the registry, you would end up with something that pretty much looks exactly like the registry.

Go take a look at all the programs on your hard disk that use the registry APIs in [consults wikipedia] in advapi32.dll. (There is a way to dump the APIs that a binary uses with link.exe; wish I could remember the command right now.)

Pretty much every executable file uses the registry, and expects keys to be in certain places in the registry. The APIs for getting/setting stuff in the registry are not going to go away for the next 10 years.

What about making a brand new son-of-registry, with new APIs, that new apps will use?
This will fix a bunch of problems (because you would be able to sidestep the mistakes you made while designing the current registry; add more metadata to keys to not roam, etc)

...but it would be decades before application developers will use it. (Because nobody is going to target their apps to Windows 7 only; they would wait before Windows 7 was the oldest OS out there before relying on that API. A lot of our external application developers only use APIs that have been in since Windows 2000. Sigh.)


Eric said...

The solution to this problem, in my mind, is that Microsoft needs to build a stronger exclusivity incentive into the next version of Windows for developers. For example, most applications for the Mac are written to run on the current release and the previous release of the OS, which means Leopard and Tiger. Most applications I can think of for Windows are made to be compatible with Windows 2000, XP, and Vista, if not Win9x stuff as well. That's more than 10 years of compatibility you're making yourself accountable for. If Windows 7 doesn't really have any major architectural changes, why not build something really incredible into that product and use that as an exclusivity incentive not only for consumers, but for developers too? Give everybody some concrete to want Windows 7. Make it desirable. I do sincerely understand why compatibility is crucial to vitality of Windows, but you can't run with the wind of innovation when you're tied to the sails of tradition. If Vista breaks so much stuff, why not build Windows 7 to only have backwards compat with just Vista? That would take care of a lot of cruft, would it not?

Aaron Axvig said...

Eric: Your last thought doesn't make too much sense...if Windows 7 is compatible with Vista, 7 is in turn also very compatible with XP/2K because Vista itself is very compatible with those. Hence "running with the wind of innovation" would require a huge break in compatibility with ANY Windows that is out there.

Steve said...

aaron: I think that he simply means to be compatible with Vista specific software (ie software that doesn't run on Vista with the backwards compatibility 'layer').

Tom Kirby-Green said...

I personally think the only way to 'deal' with the legacy of the Windows Registry is to finish what Vista started with file and Registry access virtualization of protected region and virtualize the whole darn thing. I don't see why existing apps can't continue to use existing registry APIs that are hooked (much in the same way that ShimEng.dll and ApLayer.dll hook CreateProcess etc on Vista) so that the actual replacement backing store for the registry couldn't have proper transactional semantics.

Indeed taking this further (and speculating wildly about where MSR projects like Singularity etc might go) why not do what Apple did to support OS 9 on OS X and virtualize the whole Win32 API. You wouldn't need the binary translation and instruction set emulation parts - but it would let MS, finally, move beyond Win32. Presumably by Windows 8 or 9 we'd be in a position where 64 bit was common place - so you'd have the address space needed to really allow such a compatability layer to 'breathe'....

Eric said...

@aaron axvig, steve is exactly right, but let me refine that point a bit more. The great thing about Windows is that it has maintained compatibility with so much legacy software in spite of its advances over the years. Flip the coin over, though, and that same asset becomes more and more of a burden with each successive Windows release. With all the layer-model engineering that went into Vista (see Larry Osterman's post about layer court) , the Windows team has got to have a better grasp than ever of how to elegantly remove old stuff that needs to go, and deprecate old stuff that should never be used again. Furthermore, knowing that should give them much clearer ideas about transition pathways for developers to use less crufty API. Microsoft needs to draw a line in the sand with Vista and make Windows 7 a platform that developers will want to write against and that consumers will want to buy new, upgraded "Windows 7-compatible" software for. Of course, it may take till Windows 8 to make that transition happen, but it needs to happen at some point, and the sooner the better in my mind.

someone said...

Maybe MS can change the way the registry is loaded into memory or something along similar lines so that at least performance is not hampered? I currently install most new apps I haven't tried including free and retail ones in a virtual machine and I also backup the registry using ERUNT (which is an excellent tool) and then restore it when I uninstall an app installed directly on the system.

Or maybe MS could use registry monitoring and virtualization to aid complete cleanup when that app is uninstalled? Apart from the other overhead, the large registry size in Vista is also what hampers its performance.

As for keeping Windows 7 attractive, they should make it attactive from the developer and CONSUMER side. Develop some nice high-end pro type apps and keep them locked and downloadable for Windows 7. No bundling issues, no crying "Where are the killer apps", no argument about the incentive to upgrade.

bluvg said...

I commented in the original post, and the "son-of-registry" idea is pretty much what I was suggesting.

Someone else mentioned virtualizing the registry, and that is also what I was thinking--existing apps don't know they're dealing with anything new, but the back-end architecture could change significantly. What about something along the lines of the IIS metabase? But I would suggest making it distributed with predictable paths, rather than lumping it into either a system or user file. Put the app-specific registry file under the app's folder in Program Files, and the user-specific app registry files in corresponding folders under the Roaming folder in their profile. When you go to uninstall something, you can be sure that it is fully uninstalled by simply deleting folder in the Program Files, plus you can simply drag-and-drop folders for installation, with the settings already configured. MacOS-like, yes, but without sacrificing the benefits of the registry, which would exist as a subsystem that manages the lot. Plus, put in some PowerShell intelligence, and you solve some tricky management issues--for example, you could edit offline user profiles (roaming or local) without using login scripts or other methods. Or quick and dirty, you could edit it with Notepad.

I also like the idea of a "default settings" regeneration option or automatic backup copies (perhaps via VSS), where you can delete the registry file and it gets regenerated with either default settings or reverts to a backup automatically. And if something gets truly hosed, you just copy a "known good" registry file for the app from another computer, network share, etc.

You would need to market this appropriately, though--you need to make sure that people know that "it's not the 'registry' anymore" yet it's backwards compatible. Call it something else--it has a psychological effect. If people think it's "a warmed-over registry," they'll be much less enthused. If it's a totally redesigned approach for settings storage in Windows that sets a new bar for all OSes--yet it contains a backwards compatibility layer that truly works--then you've got a huge, huge winner on your hands.

Technoid said...

I don't really understand the intricacies, but the registry has always been a PITA. I used to love my Amiga. Copy the program from one drive to another and it works... no installation needed, just put it there, double click and it works. I believe any version of Windows is overly complex. I haven't used my Mac in a while, but it's easier there, too. Want to move Photoshop to a different disk? No problem, drag, drop, and it runs.

Steve said...

@technoid: there are licensing issues with the 'works wherever' approach. I'm not sure exactly how Apple solves this (if they do at all), but I think that if licensing security was implemented in an elegant way on Windows, it would be a nice feature.

Viking said...

Soma, so the registry replacement would have to look like the registry because no one wants to change their apps.

Oh and the 64bit model is LLP because nobody wants to change their apps.

And the windows driver model will stay a marginally prettier wrapper (UMDF/KMDF) over a dead horse (WDM) because nobody wants to change the way they do their drivers.

And bits of the desktop UI (quicklaunch) are somehow identified as part of IE (docs settings\user\local\app data\ms\ie\quicklaunch) and that'll stay that way cause "yes mr. commissioner, IE is part of windows".

You know what, i actually don't care much for microsoft anyway, so by all means stick with that approach and all the best... :)

emuLOAD said...

The problem with all radical changes is obviously the difficulty developers will have in having to "change their ways". When something has been working allright for so long, changing it seems only daft to them. From a detached standpoint I agree that redesiging many features in Windows could be beneficial, HOWEVER one most not loose contact with the reality of Microsoft. While thye are a technological company, they remain a business who must maximise its profits. Unfortunatelly the vast majority of people (including MANY developers) are not very happy to upgrade themselves.

This must be taken in consideration, as it has been a crucial part of the Windows success story. Obviously it would be possible to completelly redesign the registry, implement a completelly new API layer, and at the same time keep some form of transparent compatibility with the old system. That however adds overhead and introduces the great risk that most "normal" developers will stick indefinitelly with the compatibility mode, as it makes no sense for them to upgrade. Clearly I'm not talking Adobe Photoshop, but huge expensive packages are NOT the main selling force of windows. People like to download any old pice of junk YOUTUBE2AVI etc. applications, and it is unlikelly that all those developers are going to go out of their way to redesign their 19,99 $ shareware anyways.

The problem is that there probably is no real solution and MS has to make a choice between tecnological advancement and short and middle term profit.

It is auspicable that changes are given precedence over overly-abused backwards compatibility, but was Microsoft to release an OS that required applications to be designed FOR and EXCLUSIVELY FOR Windows ### people would just hate them, probably even more than if they added no new features whatsoever.

Just look at DirectX 10.

Viking said...

I agree kinda, and nobody claims it would be easy to fix past mistakes or simply move onto a better way of doing things.
But if you want to make an omelette you gotta break some eggs.

Plus, if you make 80% profit on each copy of windows; then maybe just maybe don't burn it all on consumer electronics and pretending to have colored balls, but instead find a way to move forward. Alternatively, feel free to stay mediocre and reduce the price, but you can't have it both ways.

Old apps could get a virtual per-user-per-app registry to talk to while the rest of windows moves on...whatever - there's a thousand approaches.

As for the whole "devs won't use your features cause they'll stick with the classic stuff that works everywhere" shtick. Sorry, but that is just the worst possible attitude. Plus i think you're example of DX10 is a good one, because it shows the patience that's required. If dx10 versions of games are better than dx9 versions of games and if devs find it easier to code to dx10 than dx9, then there's nothing to fear. It's just a matter of patience.

Where do YOU think windows will end up the way it's going with it's
.) 64 bit binaries in "System32" and 32bit binaries in "SysWOW64"
.) a registry with each hive having a sub-folder-clone of itself for the other bitness
.) a 64 bit environment where longs are 32 bit
.) a single file is used to keep a user's every preference for every application installed on every computer (roaming)
.) *insert your favourite pet legacy hate here*

In the end devs want to make the least changes just for the sake of a new version of Windows - true. But devs also want to program a clean and well designed, logical environment.
So you're substituting short-term shrill screams (thing-x has changed!), for constant grumblings (god i hate windows...)

sorry bout the length.

emuLOAD said...

I could never accuse anyone of being verbose for I am guiltyer than anyone on that account :P

The trick is that in realty not so many people ACTUALLY hate Windows. And for the long term, I agree, all that is needed is patience, but that is something you have to convince the suits will have a good ROI.

Here you say "Plus, if you make 80% profit on [...]"

Well the thing is that they can, or at least they have been able to so far, and they have NO incentive (talking about the business not the engineers) to bring forth any change that could potentially undermine that. As we saw with IE, they are unlikelly to make revolutions unless they are forced to by impending doom. far from saying it is a good thing, I am saying they cannot be hated for that, as its simple business practice that -while perhaps stupid from an engineering standpoint- is perfectly sensible money-wise.

Again, it can only be my hope that they put as much effort in their future version of windows to make the system as good as possible, for as a user that is what I am the most interested in.

Viking said...

Thanks for the reprieve on the verbal diarrhoea .. :)

I agree again with what you're saying. There's no direct short-term money incentive for suits to make these kind of decisions.... Just like politicians don't have a direct incentive to put in a policy or change that will have a short term negative effect, but a huge positive effect more than 4 years down the track...

On the other hand this is a blog supposedly by a windows dev with some anonymous "no-holds barred" opinions. An engineer - passion for excellence and all that gumpf. But his viewpoint seem to reflect the management thoughts quite a bit which is... disappointing. Then again i suppose you can't expect management to have one agenda and it to not filter down to the code monkeys.

As for Microsoft / Windows being liked or disliked by x percentage of people - there's no way to determine this accurately either way so i'll just drop that point...

In summary i agree, it's the tempting thing to do (or rather not do), but i strongly disagree that it's the "sensible thing to do money-wise". Particularly at a point in time when you're positively rolling in money and talent.

emuLOAD said...

Well, what would be sensible then? They at this point in time are not yet threatend by the likes of Linux or Apple MAC OS. Why spend more than the bare minimum?

While major changes could potentially bring in a larger appreciation of the product reflected in later stronger sales, at the same time they pose a much bigger risk factor. When doing ROI analysis (a far overestimated and dumb tool, but still widely used) Delayed gains and increased risk both work against the single benefit provided (potentially) by the change.

That is what makes it a sensible thing to do. (Not neccesarely the only way to approach a business decision, and obviously I have no idea of what criteria they use at Microsoft, yet a probable scenario)

By sensible i mean "which makes sense" (from "sensata", I'm italian :P) as opposed to "ideal" or "wise"

Dave said...

I've read a lot of stuff (mostly all the same in different tastes) about this WinMin, and I really hope you guys at Microsoft are really doing it!
For the registry thing, why don’t you do like Apple does? I mean , if this microkernel is really that fast and good as they say around, just virtualize a XP or Vista like ambient (with all the stuff, registry included). I mean, apparently Microsoft is working hard on virtualization, with Virtual PC and other things. It would be easy to “force” (ask?) AMD and Intel to put special virtualization instructions on their processors. Once the developers and the market sees how much performance Windows 7 has, they will come to you praying to develop drivers and programs that runs natively on the new kernel.
Isn’t time to start with a new, solid and fast OS? Geez you have so much resources to do this… just do it! Time to put the 1990s programs in a closed sandbox that runs inside a whole new system. And screw the compatibility with a stupid printer made by some unknown manufacturer.
But I guess it’s a matter of having the guts or not having it too
By the way, keep working! I really do like Vista and I’ll keep supporting the Win family!


Viking said...

Apple's OS X does not have a microkernel, it has a monolithic kernel. To my knowledge there are no OSes around based on microkernels.
The reason for this is that microkernels in their current design, have very large performance penalties.

btw, anyone who replies with GNU HURD should be voted off the internet.

Dave said...

Yes, I know that OSX has not a microkernel. My English’s not as good as I want and so I failed to explain me.
What I wanted to say about Apple is that when they moved to a new system from os9 to osx, they just included the classic mode to support the old programs (ok, not in leopard anymore). And also when they switched from Power PC to Intel they just build Rosetta... If MS hypothetically decide to start fresh with a new base, why couldn’t they do like Apple did?

Bill said...

Go back to .ini files.

At least with an .ini file you could move an application on the hard disk without breaking it.

Viking said...

Sorry Dave i miss-understood what you meant.

I do think you might see Apple's move from 9->10 as simpler than it was.

1.) - Classic environment. This is where they stuck a copy of OS9 into OSX and get it to fire up whenever you run an OS9 app.

Problems: Security; As the system started up a copy of OS9 for the user, everything running in OS9 had root access to the filesystem. OS9 didn't have a full security model or permissions so this was generally simpler to do.
Can you imagine having to look after two OS' file permissions on disk. Two sets of user accounts, etc... Or alternatively everything on the PC runs under the same account in the windows-classic environment... also not nice.

2.) Carbon. You seem to have forgotten Carbon. This is where they retooled and trimmed the old OS9 Toolbox API's to make then work in OSX.

Problems: They wanted to just provide the classic environment and get developers to code for the native OSX API called Cocoa. The developers told them to get bent. So instead they had to modify the Toolbox environment to fit OSX. This took them literally years to do (i think around 4 years), particularly the integration with Cocoa.

Lastly, Apple's scenario back then was a lot different to windows' predicament now. I agree they need to finally start moving towards the future and leave old crud behind, but i don't know how much of Apple's OS migration is useful to Microsoft's current situation.

Paul said...

Why not do something innovative to keep the backwards compatibility and at the same time be able to move Windows 7 forward with many modernizations, such as updating/modernizing the Registry. What comes to mind is the Rosetta compatibility built into OS X Tiger ad Leopard (or even the 68K emulator (which has been said to have saved the company) built into the MacOS when Apple moved from the Motorola 6800 family of processors to the PwerPC processor. This allowed Apple to break from its past to modernize its hardware and software while still retaining compatibility with older software.

Microsoft seems to have difficulty modernizing its operating system, and it shows (i.e. the Registry). If Microsoft would say, as Apple has more than once, that we will only take backwards compatibility so far, then there might be a chance the next version of Windows might be as good, or better, than OS X, Unix and Linux. Modernize the Windows OS. Don't be so concerned if the process of modernization breaks compatibility. Do as Apple had and build into Windows a compatibility layer similar to Rosetta compatibility layer which allows programs written for PowerPC Macs run on Intel Macs. I believe 90% of all PowerPC software runs fine (if a bit slower) on Intel Macs.

What is holding Windows back as a modern OS is its unwillingness to give up backward compatibility with older software. There doesn't have to be a compromise between modernizing the Windows and retaining backwards compatibility. I am running MacOS 10.4 and have a few programs which are 10+ years old which run perfectly.

Your blog makes many references to Apple, the Mac and OS X. Apple must be doing something right for you, a Windows OS developer, to devote so much space in your blog discussing Apple, the Mac and comparing Windows to OS X>

Rave said...

first off as far as this new registry only being set for windows 7 and not other windows versions what microsoft would need to do is have a registry emulator (sort of like a windows emulator)only designed specifically for the registry. In addition to both the new registry (repository without .exe files and the virtual registry emulator which supports .exe files designed for previous windows generations) what needs to be done is to have both of them password encoded. That way if a virus does want access to the registry it will have to know the password to gain access to either the repository or the virtual registry emulator (This way it solves the reverse compatability issue without falling back on previous window design flaws and old source codes to do this)And this new registry can avoid using all .exe files making way for newer and better technology to come without being held back by legacy issues. The virtual registry emulator with password encoding is what is required to do all this. And password encoding for the new repository as well. Virtual emulators work for multi operating systems so why cant the same concept be given here to this registry repository approach

Dave said...

Paul, that was just what I was saying!

Anthony said...

I think Apple is much smarter by using XML files. They can be compiled to a binary format for speed if really necessary (though nowadays, how often is it really?) but you can always convert them to text and the point of text is that you can always fix it with a text editor when you have to.

But Microsoft screws that concept up always. Outlook PST files, as another example. Mail should be stored as individual text files or as one big text file with separators (though I dislike that) and separate index files. Then when the index breaks (and indexes ALWAYS break), they can be rebuilt without danger of losing anything.

9999 said...


明男 said...

情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,情趣,美國aneros,rudeboy,英國rudeboy,英國Rocksoff,德國Fun Factory,Fun Factory,英國甜筒造型按摩座,甜筒造型按摩座,英國Rock Chic ,瑞典 Lelo ,英國Emotional Bliss,英國 E.B,荷蘭 Natural Contours,荷蘭 N C,美國 OhMiBod,美國 OMB,Naughti Nano ,音樂按摩棒,ipod按摩棒,美國 The Screaming O,美國TSO,美國TOPCO,美國Doc Johnson,美國CA Exotic,美國CEN,美國Nasstoy,美國Tonguejoy,英國Je Joue,美國Pipe Dream,美國California Exotic,美國NassToys,美國Vibropod,美國Penthouse,仿真按摩棒,矽膠按摩棒,猛男倒模,真人倒模,仿真倒模,PJUR,Zestra,適趣液,穿戴套具,日本NPG,雙頭龍,FANCARNAL,日本NIPPORI,日本GEL,日本Aqua Style,美國WET,費洛蒙,費洛蒙香水,仿真名器,av女優,打炮,做愛,性愛,口交,吹喇叭,肛交,魔女訓練大師,無線跳蛋,有線跳蛋,震動棒,震動保險套,震動套,TOY-情趣用品,情趣用品網,情趣購物網,成人用品網,情趣用品討論,成人購物網,鎖精套,鎖精環,持久環,持久套,拉珠,逼真按摩棒,名器,超名器,逼真老二,電動自慰,自慰,打手槍,仿真女郎,SM道具,SM,性感內褲,仿真按摩棒,pornograph,hunter系列,h動畫,成人動畫,成人卡通,情色動畫,情色卡通,色情動畫,色情卡通,無修正,禁斷,人妻,極悪調教,姦淫,近親相姦,顏射,盜攝,偷拍,本土自拍,素人自拍,公園露出,街道露出,野外露出,誘姦,迷姦,輪姦,凌辱,痴漢,痴女,素人娘,中出,巨乳,調教,潮吹,av,a片,成人影片,成人影音,線上影片,成人光碟,成人無碼,成人dvd,情色影音,情色影片,情色dvd,情色光碟,航空版,薄碼,色情dvd,色情影音,色情光碟,線上A片,免費A片,A片下載,成人電影,色情電影,TOKYO HOT,SKY ANGEL,一本道,SOD,S1,ALICE JAPAN,皇冠系列,老虎系列,東京熱,亞熱,武士系列,新潮館,情趣用品,情趣,情趣商品,情趣網站,跳蛋,按摩棒,充氣娃娃,自慰套,G點,性感內衣,情趣內衣,角色扮演,生日禮物,生日精品,自慰,打手槍,潮吹,高潮,後庭,情色論譠,影片下載,遊戲下載,手機鈴聲,音樂下載,開獎號碼,統一發票號碼,夜市,統一發票對獎,保險套,做愛,減肥,美容,瘦身,當舖,軟體下載,汽車,機車,手機,來電答鈴,週年慶,美食,徵信社,網頁設計,網站設計,室內設計,靈異照片,同志,聊天室,運動彩券,大樂透,威力彩,搬家公司,除蟲,偷拍,自拍,無名破解,av女優,小說,民宿,大樂透開獎號碼,大樂透中獎號碼,威力彩開獎號碼,討論區,痴漢,懷孕,美女交友,交友,日本av,日本,機票,香水,股市,股市行情, 股市分析,租房子,成人影片,免費影片,醫學美容,免費算命,算命,姓名配對,姓名學,姓名學免費,遊戲,好玩遊戲,好玩遊戲區,線上遊戲,新遊戲,漫畫,線上漫畫,動畫,成人圖片,桌布,桌布下載,電視節目表,線上電視,線上a片,線上掃毒,線上翻譯,購物車,身分證製造機,身分證產生器,手機,二手車,中古車,法拍屋,歌詞,音樂,音樂網,火車,房屋,情趣用品,情趣,情趣商品,情趣網站,跳蛋,按摩棒,充氣娃娃,自慰套, G點,性感內衣,情趣內衣,角色扮演,生日禮物,精品,禮品,自慰,打手槍,潮吹,高潮,後庭,情色論譠,影片下載,遊戲下載,手機鈴聲,音樂下載,開獎號碼,統一發票,夜市,保險套,做愛,減肥,美容,瘦身,當舖,軟體下載,汽車,機車,手機,來電答鈴,週年慶,美食,徵信社,網頁設計,網站設計,室內設計,靈異照片,同志,聊天室,運動彩券,,大樂透,威力彩,搬家公司,除蟲,偷拍,自拍,無名破解, av女優,小說,民宿,大樂透開獎號碼,大樂透中獎號碼,威力彩開獎號碼,討論區,痴漢,懷孕,美女交友,交友,日本av ,日本,機票,香水,股市,股市行情,股市分析,租房子,成人影片,免費影片,醫學美容,免費算命,算命,姓名配對,姓名學,姓名學免費,遊戲,好玩遊戲,好玩遊戲區,線上遊戲,新遊戲,漫畫,線上漫畫,動畫,成人圖片,桌布,桌布下載,電視節目表,線上電視,線上a片,線上a片,線上翻譯,購物車,身分證製造機,身分證產生器,手機,二手車,中古車,法拍屋,歌詞,音樂,音樂網,借錢,房屋,街頭籃球,找工作,旅行社,六合彩,整型,水噹噹,貸款,貸款,信用貸款,宜蘭民宿,花蓮民宿,未婚聯誼,網路購物,珠海,下川島,常平,珠海,澳門機票,香港機票,婚友,婚友社,未婚聯誼,交友,婚友,婚友社,單身聯誼,未婚聯誼,未婚聯誼,婚友社,婚友,婚友社,單身聯誼,婚友,未婚聯誼,婚友社,未婚聯誼,單身聯誼,單身聯誼,婚友,單身聯誼,未婚聯誼,婚友,交友,交友,婚友社,婚友社,婚友社,大陸新娘,大陸新娘,大陸新娘,越南新娘,越南新娘,外籍新娘,外籍新娘,台中坐月子中心,搬家公司,搬家,搬家,搬家公司,線上客服,網頁設計,線上客服,網頁設計,網頁設計,土地貸款,免費資源,電腦教學,wordpress,人工植牙,關鍵字,關鍵字,seo,seo,網路排名,自然排序,網路排名軟體,