Problem: I relied heavily on NTFS Junction points in Windows XP, even though they apparently were not an "official" feature of the operating system. Now MSFT has generously made NTFS Junction points an official part of Vista, but apparently they also intentionally broke them. Now my WinXP-created junction points on portable USB drive don't work when I plug that drive into a Vista box.
Questions: Does anyone have a script that will force NTFS junctions created on XP to work correctly within BOTH Vista and XP? Is there documentation or a spec that explains what MSFT did to cause this breakage?
Update: Thanks, Ulrich and Scott, for your follow-up questions. The tool I used to create the junctions was Systinternals Junction v1.05 although I can't say for sure that all of them were created with that specific version of the now-MSFT-hosted app.
As far as how the junctions are used ... assuming an external "Q Drive" device:
1) Some items on the Q Drive are junctions that point from one place on the Q Drive to another place on the Q Drive (e.g., cases where I needed to have a folder in more than one place, and a traditional .lnk style shortcut would not work)
2) Some items are junctions that point from the C Drive directly to locations on the Q Drive. These items obviously do not work when the Q Drive is not actually connected box (XP or Vista), but when connected on Vista, the junctions do not work as on XP.
Junctions and symbolic links are two different types of NTFS objects and are not exactly the same thing. Why your junctions are not recognized in Vista is a mystery, but the junction functionality still exists in Vista and it not purposefully broken.
You can use mklink (http://technet.microsoft.com/en-us/library/cc753194.aspx) to create soft links (the default), hard links (/h), or junctions (/j). The biggest improvement of sym links over junctions is sym links can reference files OR directories (junctions are directory only) and the can reference network shares as well (junctions cannot).
But the bottom line is they are different. Can't tell you why your existing junctions are not recognized by Vista though. You can still create them as described above.
There freeware utility referenced in another post (LinkMagic) is your best bet to getting your junctions working again. Or recreate them with mklink.
Why don't you try with this program (freeware) to create the links. Apparently Windows Vista needs a different version. I have tried both versions (XP and Vista) and they work. I know it doesn't have to do with your specific problem, but given that there are separate versions for each OS, there might be diferences in the way Junctions are created.
The tool you have used is rather old (2007) and doesn't mention Windows Vista. I know that MSFT did change something in the Junction Points in order to add some functionality they wanted to use. Vista is more authoritative when it comes to Program Files folders and such.
Besides the Linkmagic program already suggested in one of the previous comments, Link shell extension is another good program to manipulate (and check) links and junctions:
http://schinagl.priv.at/nt/hardlinkshellext/hardlinkshellext.html
Both of these programs can tell you what the existing links/junctions point to, and what they are. This may help you in figuring out what's wrong.
What you trying to link to? Are you linking TO your portable drive or FROM your drive? Are you using "mklink /d"?
Junctions points within the same volume should work - they should be hardlinked directories.
Have you tried if the USB drive works between XP machines? It might not work.
I know that for vista the volumes are NOT identified by path (Q:) but by volume GUID.
The $MFT_REPARSE_POINT format might have changed from XP to Vista to accomodate this.
Under Vista, this mean that even if your Q drive is suddenly X, the junction point shoudl still work, where under XP it would be broken.
Christoph Hochstätter made an "mklink.exe" substitute for Windows XP that can actually create
genuine Vista (et al.) symlink reparse points, but warns that they may not be usable under
the Windows XP OS. However, Cygwin will recognise them under XP. And, of course, Linux ntfs mounts.
Not sure if this will be of much help though...
http://www.zdnet.de/windows_system_verbessern_mklink_f_uuml_r_windows_download-39002345-30973-1.htm
Related
Situation: I'm on a stand-alone development computer running Windows 7. Not connected to any Windows Server. Would like to test a Window application's ability to use UNC paths. Will be transferred later to a Linux server (not at my location), hence the desire to use a cross-platform path mechanism (UNC) (//servername/sharename), rather than a Window's mapped drive (X:\foldername).
The application is Autodesk Maya 2014. A project's main file contains many references to other files. These file references can be relative paths ("subfolder/filename.ext"), absolute paths ("H:/projects/this_project/subfolder/filename.ext"), or UNC paths ("//servername/projects/.." or "servername/assets/..").
The app permits forward slashes, and maps those to the correct character on different OSes. Wherever possible, I use relative paths.
But I have a situation where a plug-in is not correctly working with relative paths, so I have resorted to using some absolute paths. It has been requested that I change these from the current mapped drive form, to UNC paths. REASON: the data will be transferred to a render farm, running Linux. A Linux version of the app will be used. (So my question isn't about accessing Linux files from my Windows box; it is about setting up all the data so that when everything is moved to the render farm, it will still run.)
Due to the combination of plug-ins and features we are using in Maya, I am not 100% certain I can convert all paths to relative form. (Questions there for Maya forums.) So as a fallback, I need to test with UNC paths. Am asking what it would take to set this up on my Windows 7 PC, without actually connecting to a server computer. (Don't have Linux nor Windows Server set-up at my location.)
I don't normally do network-related programming, nor server programming, so the various possible solutions are not familiar to me.
Googling suggests some basic techniques, that may or may not be relevant. Before I spend more time on this, want to know if I am going in the correct/easiest direction.
installing a local DNS server and editing its hosts file. Such as:
http://sourceforge.net/projects/acrylic/
http://sourceforge.net/projects/dhcp-dns-server/
.. but I don't have a domain name, I just have a (future) network computer name, so this is not relevant?
Editing LMHOSTS file
.. but this is just for mapping between a name and an IP address?
multiple NetBIOS names (OptionalNames)
Mentioned here:
http://www.mediamonkey.com/forum/viewtopic.php?t=51722&f=1
Which refers to:
https://serverfault.com/questions/23823/how-to-configure-windows-machine-to-allow-file-sharing-with-dns-alias
.. But that is talking about DNS, so is that relevant?
What I have succeeded in doing so far:
In Command Prompt (Run as Administrator):
net view \\localhost
or
net view \\mycomputernamehere
Lists shared folders on my PC. E.g. H:\temp Properties / Sharing, shared as "HTemp", which is listed.
So I think all I need to do is:
A. Share any folder with the desired name, e.g. "projects".
It will then be visible as "\\localhost\projects".
B. Convince Windows to use my local computer when I ask for "\\servername". I can then use "//servername/projects" in the app, which will ask Windows for "\\servername\projects", which then would be converted by Windows to "\\mycomputernamehere\projects".
... this (B) is the part I need help with. (3) above sounds like it is a solution. But to me it is rather arcane (editing the registry). Will it accomplish what I need? Is there an easy solution that doesn't involve registry editing?
And yes, somewhere along the way it dawned on me that the simplest solution is to rename my computer to "servername". I'll probably do that for this week.
But I'd still like to learn a way to alias my computer name, to fake a UNC path without actually renaming my computer. And without relying on a second computer acting as server.
This is a late answer, but for future reference:
Your suggestion of multiple NetBIOS names (OptionalNames) has worked for me to allow a Windows machine to accept UNC paths under other computer names.
For completess, you can combine this with adding the same alias's to the hosts file with the localhost ip 127.0.0.1 so IP traffic will always be redirected.
Maybe use the UNC version of localhost?
\\localhost\c$\tmp
Will map to your local c:\tmp folder.
I have a .exe file in my pen drive sitting in a long chain of directories
(driveLetter:\dir1\dir2....\dir8\program.exe)
Now I don't wanna go through all those directories to get to the file and run it,
Problem is that in Windows7, running a .exe file with the autorun.inf open command doesn't work anymore in pen drives but it does in CDs, that's why I wanna make my pen drive appear like a CD to windows upon insertion.
Please don't ask me if I'm writing a virus here, cuz I'm not.
Any ideas how can I achieve this ?
if making it appear as a CD won't work, is there a way to run the .exe file
(I know, this might be a separate Q)
Thank you so much for anything you can provide me with.
You can make a flash drive use autorun by having the autorun and exe file in the default directory (i.e.: not a dozen folders deep). That's how I've done it when installing W7 on computers without a CD drive.
Here's what Windows 7 autorun.inf looks like
[Autorun.Amd64]
open=setup64.exe
icon=setup64.exe,0
[Autorun]
open=setup.exe
icon=setup.exe,0
It's pretty straight-forward: the top one is for a 64-bit OS, while the bottom is for 32-bit.
Since 2011, Microsoft has removed the autorun.inf option, so it will not work, not even if CD drivers will replace the current drivers. Both CDs and flash drives can't be automatically started without at least a prompt shown to the end user. That is for security reasons.
I have an application written in Delphi 2006 that was working fine in Windows XP. I packed the application using Inno Setup, using Program Files as the default folder. A few users migrated to Windows Vista and Windows 7. The issue here is that the application creates some files inside its installation folder by its own. This was working in XP but in Windows Vista the users were having problems with the created files (they don't appear and so on). After investigating the users' reports I discovered KB 927387: "Common file and registry virtualization issues in Windows Vista or in Windows 7."
Running the application with administrator rights just solves the problem, but that is (I think) an awful workaround. I would like to know if there are any directives or tips for making the application compatible with Vista and 7, because more users will migrate to these OS soon.
You need to re-write your application to store its files in the proper locations, even in XP, but especially in Vista onwards, particularly if UAC is enabled. This is becoming more and more important to get right as Microsoft keeps locking down and enforcing its security models with each new OS version. The rules for how to properly manage application- and user-related files is documented on MSDN, for example: "Application Specification for Microsoft Windows 2000 for Desktop Applications, Chapter 4: Data and Settings Management" and "Application Specification for Microsoft Windows 2000 for Desktop Applications Appendix A: Best Practices" (yes, they are old, but are still quite relevant). Look at SHGetSpecialFolderLocation(), SHGetFolderPath(), SHGetKnownFolderPath() and other related functions to help you.
For Vista/Win7, your app can't put the files in a subfolder of Program Files / Programs unless UAC is turned off or the app is running as elevated. Note that "elevated" does not necessarily mean "logged in as Administrator." Non-administrator users can elevate, and Administrator isn't necessarily elevated.
If the app does attempt to write to Program Files but is not elevated, the OS will either block the app or "virtualize" the write (put the files somewhere else), depending upon how UAC is configured. Neither one helps the app succeed at what it was trying to od.
So it needs to put them somewhere else. Where depends on why the files are being created, and you haven't told us that. You can read this article to learn about the options. Note that in addition to the user's AppData and Roaming folders, there is also an "All Users" (shared) profile.
You should probably look at this article and screencast, which discusses UAC in depth from a Delphi point of view.
Files you create for use by your application other than at installation time should go into the ProgramData directory if its global to the workstation, or into the users ApplicationData directory if its specific to the user.
For cases where you absolutely must place a file in the program files directory, you can use com to request elevation. This is discussed in great detail, and delphi specific bits are also available. One example that I have used this is in patching my users installation base. They are warned by UAC that the system needs to make changes, so if your doing this as an automated task, you might need to rethink the logic to be more user driven.
Here is another article, by Zarko Gajic, which shows how to get different system directories. Also have a look at this related question.
I had a similar enquiry here (Stack Overflow).
In the end I realised that I needed to put my application into Program Files at install time (requiring UAC/elevation) and then store my app's data in the user's App Data folder. I had to change the way my program generated 'default' configuration settings and also where I was saving this stuff, but it was worth the effort in the end - we ended up with something that installs and runs fine on XP, Vista and Windows 7.
The only UAC hit we get is at installation time, which makes sense to me (and you get a similar hit at install-time on the Mac too). We didn't have any data that would be common to all users in this particular case but I would have looked at the Program Data special folder if that had been the case.
The installer software we use (Setup Factory) made this fairly straightforward (we just wrote a small bit of code to detect XP versus Vista/Win7 and choose the right special folder accordingly). It would be easy to do this in Inno Setup too, from what limited experience I have of it.
I was reading the post Installation file names in Windows Vista when I thought about Installation File Names. I'm a addicted software downloader, and frequently I've got installation names like "setup.exe" or "install.exe", that says nothing about the program to be installed.
I think that an installation file must be like:
Install[ProgramName][ProgramVersion][Platform].[exe|msi|etc]
or
[ProgramName][ProgramVersion][Platform].Setup.[exe|msi|etc]
What your thoughts?
I much prefer descriptive install file names. Sometimes, you want an emergency 'restore' disk to get a machine up and running even without internet connectivity. When all your installs are named "setup.exe", you either have to rename them all, or create a directory with a descriptive name for each one.
An example of where such a disk would have been really handy was when I took my brand new laptop in to work to use while I upgraded my desktop to Vista 64, and then Windows 7. I only have one wired LAN point, so my laptop needed a wireless connection for internet access, to download my installs. I had to download them all on my desktop, and then transfer by flash drive to my laptop. Very inconvenient.
Not sure this is entirely programming-related... but installer files are usually meant to be transient. You download them, run them, and delete them. (Or at least, I think most people do) So it doesn't matter much what the filename is.
I don't think there's any reason not to give the installer a descriptive name... but I certainly wouldn't say it "must" have one.
For CD-Rom based installation, I'd suggest sticking with SETUP.EXE which helps with autorun detecting software to install from the disk.
For downloadable files, just add the appropriate manifest to the EXE and Vista won't have a problem with it. I'd suggest something semi-descriptive, but there's no need to go into great detail unless it's something like hardware drivers that a person may archive off for reuse, otherwise the file name is confusing to non-technical people.
On OS from win 2000 or later (any language) can I assume that this path will always exists?
For example I know that on win xp in some languages the "Program Files" directory have a different name.
So is it true for the System32 folder?
Thanks.
Ohad.
You definitely cannot assume that: Windows could be installed on a different drive letter, or in a different directory. On a previous work PC Windows was installed in D:\WINNT, for example.
The short answer is to use the API call GetSystemDirectory(), which will return the path you are after.
The longer answer is to ask: do you really need to know this? If you're using it to copy files into the Windows directory, I'd suggest you ask if you really want to do this. Copying into the Windows directory is not encouraged, as you can mess up other applications very easily. If you're using the path to find DLLs, why not just rely on the OS to find the appropriate one without giving a path? If you're digging into bits of the OS files, consider: is that going to work in future? In general it's better to not explicitly poke around in the Windows directory if you want your program to work on future Windows versions.
No, you can't assume that.
Windows can be installed to a different path. One solution is to look for it by calling GetSystemDirectory (implemented as part of the Windows API).
Windows can be installed on a different harddrive and or in a different folder. Use the %windir% or %systemroot% environment variables to get you to the windows folder and append system32. Or use the %path% variable, it's usually the first entrance and the preferred method of searching for files such as dlls AFAIK. As per comments: don't rely too much on the system32 dir being the first item. I do think it's safe to assume it's in %path% somewhere though.
I would use the GetWindowsDirectory Win32 API to get the current Windows directory, append System32 to it an then check if it exists.
It might be safer to use the "windir" environment variable and then append the "System32" to the end of that path. Sometimes windows could be under a different folder or different drive so "windir" will tell you where it is.
As far as i know, the system32 folder should always exist under the windows folder.
Just an FYI, but in a Terminal Server environment (ie, Citrix), GetWindowsDirectory() may return a unique path for a remote user.
link text
As more and more companies use virtualized desktops, developers need to keep this in mind.