We're finally getting around to moving our software's documents out of the program's own directory and into "My Documents". We're also adding a "requestedPrivileges" line to the manifest to prevent further trouble with virtualization.
However if we only did that then anyone who had been running the old versions in Vista/7 is likely to lose their work somewhere within the hidden VirtualStore directory after updating. So what's the preferred way of migrating into the 21st century?
Frankly I'm a little wary of copying files around, especially as I can't seem to find a programmatic way of getting at the shadow directory, but presumably plenty of other people must have had the same problem before us.
Don't add requestedPrivileges unless you legitimately need administrative rights in order for your program to work - nothing in your description suggests that you do. That should also let you simply copy the files on the first boot as if they were still in your program directory, because any virtualization would still be in effect.
However, if you absolutely must do the migration without UAC enabled, you can find your files in %LOCALAPPDATA%\VirtualStore\path\to\file. For example, if your file would have been stored in C:\Program Files\OurApp\, you'll find it in %LOCALAPPDATA%\VirtualStore\Program Files\OurApp\.
To get the path to %LOCALAPPDATA%, you can use SHGetSpecialFolderPath with CSIDL_LOCAL_APPDATA as the CSIDL parameter.
Related
So I have been trying to build an installer for my game with NSIS. For the most part it works fine but just noticed that it seems to be skipping certain files for no reason. Or no reason I can figure out.
At first I was using this line to gather up all the files in the source folder:
File /r "${NSISDIR}\game\source\*.*"
However, I noticed that this didn't get everything. Granted it found all sub-folders and kept the hierarchy correct. There didn't seem to be any rhyme or reason to what it skipped. Then I tried listing all files and directories separately and found out why. Example:
File "${NSISDIR}\OWTD-DE\source\pygame.math.pyd"
This produces the following error:
File: "C:\Program Files (x86)\NSIS\game\source\pygame.math.pyd" -> no files found.
But that file exists, I can see it in the source folder. This was the case for all missing files. At first I thought it may be the two periods in the name, but various files have that naming convention and they are added fine. I cannot figure out how to get it to recognize these files. Any ideas?
${NSISDIR} is a define used to access the UI resources in the Contrib subfolder, you are not supposed to put your files there. Your source files should not be in Program Files, only installed files should be located there. Also, on 64-bit systems there are two Program Files folders and there are some compatibility hacks in Windows related to %ProgramFiles% so putting your source files there is not optimal. Just because you see that file there does not mean it is actually in Program Files, it could be UAC Virtualization/VirtualStore tricking you...
Normally you would keep your .nsi somewhere in the same directory tree as the rest of your files so you can use relative paths but you can also use a define if you really want to:
!define MYSOURCE "c:\foo\bar"
...
Section
File /r "${MYSOURCE}\*.*"
SectionEnd
If it still misses some files I would suggest trying Process Monitor so you can see the low-level details...
Weirdly enough, this process did not work very well on Windows Home 64-Bit but did on Windows Professional 64-Bit. I'm not sure if this an issue with NSIS itself or what, but nothing was different between the two except the OS. And there really isn't much difference between those two operating systems. However, perhaps some configuration differences between the two was the real issue.
While marked solved, I'm not really sure what the actual issue and solution could be.
I'm having issues with a few .ocx files in vb6. I have 2 components registered but when I attempted to add both into my project it says that I need to register them. I have tried copying new files into the sysWOW64 folders and still it does not work.
This occasionally happens when there is some corruption and conflict in the registry. One way to fix this is to place the two items in a folder within the project and add them by manually going to the reference and selecting that local copy, it will automatically register it as a new object and often (although not always) will fix the corruption by tagging the new path and it often resolves the issue you are facing. The only problem is that in the future projects, you may need to repeat the process or have access to the items.
The cleaner approach is to find all instances of the files on the system by doing an advanced search and finding ALL COPIES of them on the system, often they are all over the place. Once you have those paths, you need to regsvr32 /u <filepath.filename> each one to clean remove them from the registry and then place them in a common area and then register them from ONE location using regsvr32 <filepath.filename> and now things should work fairly cleanly.
Easiest way to find all instances on your machine (at least for me) is to simple go to your command prompt (if using more recent than XP, then as administrator) and then simply type:
C:
cd\
dir /s <filename.ext> > c:\files.txt
and wait until its done, at that point you open that file and it should give you all the paths to the files you need and you can easily turn the text file into a batch file by adding the commands you need to unreg and run it, voila, quick and fairly painless. If at anytime you unreg and it whines about it not being registered or can't do it, don't worry, just acknowledge and move on. Some OCX and DLL don't have registration entry points. If you register and it complains saying it can't do it, then you pretty much have no choice but to it the way I mentioned at the very beginning, by direct linking in your reference and having it drop into your project.
Final note, unless they are 64 bit compatible, you don't need and often shouldn't put them in the WOW system folder but rather system and system32 folders depending on version control and binary control of the original OCX.
I'm using Visual Source Safe 6.0d (work requirement) and I've been trying to hack together a little shell script to allow me to easily remove a source tree or warn me if I've got files checked out so I can make sure I don't accidentally delete work. Is there any way to tell if files are checked out other than checking the read-only bit on the files themselves?
VSS doesn't seem to be writing any file (I took a snapshot of the dir before and after checking out a file and there was no difference in the files listed)
I can't seem to find anything by Googling.
I also checked the vssver.scc for differences and didn't find anything.
Mind you, checking for writeable files isn't the worst thing in the world but it seems as if VSS makes several files in the source tree (*.ncb, *.scc, *.sln) writeable without me having checked anything out. I can simply exclude the files but I'm trying to find a bit more elegant solution.
You can use COM to check if a file is checked out. Take a look at the IVSSItem.IsCheckedOut property. For more on using VSS through COM see:
http://msdn.microsoft.com/en-us/library/4d44xhsd%28VS.80%29.aspx
Perhaps the most robust technique is to ask SourceSafe itself what is checked out and/or whether individual files of interest are checked out. Whilst I realize that it's not obvious how to do this in a little shell script, I'd advocate the use of PowerShell for this.
SourceSafe exposes an OLE Automation object model (also known as a COM object model), and PowerShell can talk to COM objects. If you're not familiar with this stuff, it's a lot to learn but ultimately it's worth it.
Alternatively, if PowerShell is too alien, VBScript can also be used to control COM objects.
In my working folder of a VSS project, is it alright if I make all the files/folders writable? i.e. not readonly?
It is ok, but why should you?
The read only state is a safeguard so you can't change code that is not locked. Avoiding possible merge troubles in the near future.
Edit: Ok in the comment you said that the build failed because the file was not writable. If so, then it is very strange. Especially if the error message said something about not able to access the file.
It was probably still locked by another process and changing the readonly flag removed the lock (or it just needed the delay). But as far as I know, compilers do work excelent with read only source files.
Possible problems:
Files on network drives. If the network is slow, the compiler can have trouble accessing the file.
File still open in (an other) editor. Normally this shouldn't be a problem, but you may never know.
Some code files are generated during the build. In this case they don't belong in the version system, their source (if any) does.
I have a Windows service application on Vista SP1 and I've found that users are renaming its executable file (while it's running) and then rebooting, thus causing it to fail to start on next bootup because the service manager can no longer find the exe file since it's been renamed.
I seem to recall that with older versions of Windows you couldn't do this because the OS placed a lock on the file. Even with Vista SP1 I still cannot copy over the existing file when it's running - Windows reports that the file is in use - makes sense. So why should I be allowed to rename it? What happens if Windows needs to page in a new code page from the exe but the file has been renamed since it was started? I ran Process Monitor while renaming the exe file, etc, but Process Mon didn't report anything strange and just logged changing the filename like any other file.
Does anyone know what's going on here behind the scenes? It's seem counter intuitive that Windows would allow a running process' filename (or its dependent DLLs) to be changed. What am I missing here?
your concept is wrong ... the filename is not the center of the file-io universe ... the handle to the open file is. the file is not moved to a different section of disk when you rename it, it's still in the same place and the part of the disk the internal data structure for the open file is still pointing to the same place. bottom line is that your observations are correct. you can rename a running program without causing problems. you can create a new file with the same name as the running program once you've renamed it. this is actually useful behavior if you want to update software while the software is running.
As long as the file is still there, Windows can still read from it - it's the underlying file that matters, not its name.
I can happily rename running executables on my XP machine.
The OS keeps an open handle to the .exe file,. Renaming the file simply changes some filesystem metadata about the file, without invalidating open handles. So when the OS goes to page in more code, it just uses the file handle it already has open.
Replacing the file (writing over its contents) is another matter entirely, and I'm guessing the OS opens with the FILE_SHARE_WRITE flag unset, so no other processes can write to the .exe file.
Might be a stupid question but, why do users have access to rename the file if they are not suppose to rename the file? But yeah, it's allowed because, as the good answers point out, the open handle to the file isn't lost until the application exits. And there are some uses for it as well, even though I'm not convinced updating an application by renaming its file is a good practice.
You might consider having your service listen to changes to the directory that your service is installed in. If it detects a rename, then it could rename itself back to what it's supposed to be.
There are two aspects to the notion of file here:
The data on the disk - that's the actual file.
The file-name (could be several or none) which you can give that data - called directory entries.
What you are renaming is the directory entry, which still references the same data. Windows doesn't care about your doing so, as it still can access the data when it needs to. The running process is mapped to the data, not the name.