How to find out the name of the common documents folder on a network machine - delphi

Given that I am executing an EXE file (D2006 app) on a machine across the network, how can I get the pathname to the commondocs folder on that machine, given that the EXE might have been invoked from a UNC shortcut or a mapped drive letter shortcut, and the platform of the remote machine is not necessarily known (but will be >= WinXP)?
The situation is where the client has a large number of dispersed machines, and they can't be bothered installing my app on all the PC's. So what they do is install the executable somewhere on the network and give everybody a shortcut to that. This already seems to suit them fine and there are no issues there.
At their request, I made the app read the settings from an INI file placed in the same folder as the executable. I can only assume they have configured things so that all the users can write to that folder so that the INI file can be saved back.
However, I want to change it so that the INI file is read and saved to somewhere in the commondocs folder tree on the remote machine, so that they don't need to provide write access to a Program files folder.

The machine that's running your program is the only machine you have access to. The machine where your program is stored is irrelevant. It's just a disk drive. It might not be running Windows. It might even be a NAS that's hardly running anything at all.
If the customer wants the common-documents folder of the file server to act as the common-documents folder for everyone on all the client systems, then get the sysadmin to configure a shared folder on the server and then configure the clients to use that remote folder as their common-documents folder. There is no special programming required on your part for that.
To get the common-documents folder of the machine your program is running on, you can call any of various API functions, including ShGetFolderPath. The CSIDL value you need is CSIDL_COMMON_DOCUMENTS. If you call SHGetKnownFolderPath instead, use FOLDERID_PublicDocuments.

Related

How to prevent local msmpi installation from loading system wide msmpi.dll

I'm writing a console app for windows that sets up an environment and launches (popen) various hpc-apps using msmpi mpiexec.exe.
I have an msmpi installation installed locally to the application I'm writing. All works fine and parallel processing is OK.
However, as soon as I happen to have a system installation of msmpi as well (as installed by e.g. msmpisetup.exe), my applications stubbornly loads the Windows/system32/msmpi.dll instead of the msmpi.dll that I point at using PATH. Since the system msmpi.dll is of a different version, my apps does not run.
The PATH env.var. is set within my app, and it is apparently inherited correctly by the child processes, including mpiexec.
The only remedy I've found is to either (1) Rename system32/msmpi.dll or (2) place a copy of "my" msmpi.dll into every folder in which I have a parallel executable. Both remedies are... not nice.
How can I prevent my apps from selecting the system32/msmpi.dll and use the instance that's in the PATH instead??
Thank you for any advice.
N
The standard DLL search order in Windows is documented to be
The directory from which the application loaded.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The current directory.
The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
If you want your application to check a specific location first before using the system locations, you can call SetDllDirectory in the parent application before letting it execute other binaries that require a particular DLL.

How to move Active Storage data from one machine to another

Because reasons we are trying to move a system from one machine to another one. It has several files in the storage directory. I rsynced it (using -a) to a local environment to see if everything works, but turns out not all the files are available, some of them raise an exception:
Errno::ENOENT (No such file or directory # rb_file_s_mtime - /path/to/project/storage/as/df/asdfasdfasdfasdfasdf):
Of course I checked the routes and they exists. I've been reading a bit about how Active Storage works and I maybe the URLs are getting invalidated for some reason, but why some files work? 🧐 Why the exception mentions mtime? And more importantly, how can I do the migration smoothly?
Thanks in advance
So the problem is actually the filesystems + Active Record names 😰 You can consider this a corner case: My local machine runs macOS, while the server runs Linux, so if I had folders Vf and VF on Linux, on macOS they become one (whichever is downloaded firs). Active Storage relies on case-sensitive filenames, and that's why some of the files work fine, but others are not found

Share path between server and client (delphi) application

On my LAN I have 2 applications running in server/client mode developed with Delphi (but I don't think this is important).
On server PC (where run server application) there is a USB hard disk, this hard disk have many folder and subfolder shared on LAN.
Now I need to do this:
1. The server application must send to client application a shared folder (for example "d:\folder\subfolder\", then the client application must open this path to show the files (using explorer).
2. The user, using client application, must select a shared folder (for example "\SERVER\folder\subfolder\") and send this to server application, the server application must convert this path in local path (for example "d:\folder\subfolder\") and save it inside a database.
My problem is: is there a simple way to:
1. Convert the local path to remote path before send it to client se the client can open it easily?
2. Convert the remote path to local path before save it inside database.
NOTE: the main folder or main drive of shared hard disk can be change.
NOTE2: I'd like use IP address and not windows pc name if possible because it can be change.
I hope I explained.
Thanks
If I understand you correctly you want to acces some files that are inside some shared folder. Right?
If that is true then go and acces to these files unsing the network path which is formed in this manner
\\Networkedcomputer\SharedFolderName\Subfolder\...
where:
NetworkComputer is either a name of computer that is sharing that folder or its IP adress. I asume you are interested in using of IP adresses since you already have acces to that information from your other networked components.
SharedFolderName is the network name that was chosen when specific filder was set to be shared on the network. This name doesen't even have to be the same as the name of actual folder
Subolder can be any subfolder of the share folder
In order to get networked path to your shared folder you do need to know network name of the shared folder.
Perhaps you could even retrieve this information from SelectDirectory method which shows special dialog for selecting of directory, but I'm not sure if it does support networked folders. If not you could make use of OpenDialog.
NOTE: In any case when selecting the shared folder either with the use of SelectDirectory or OpenDialog you would need to go to that folder through Network Places (Network -> MyComputerName) and not directly through MyComputer.
But if you need to aquire the shared name for any local folder programatically I think you would have to go and read that information from registry as I'm not sure there is a specific API call for this.
EDIT: The answer on SO question below refers to several Delphi components that can be used for managing of Shared network resources. So I guess you could use to retrieve the network path for a shared local folder but I haven't tried them out.
How do I remotely obtain a system's network shares and connections?

Does Windows.CopyFile create a temporary local file while source and destination are network shares?

I have a D2007 application that uses Windows.CopyFile to copy MS Word and PowerPoint files from one network folder to another network folder. Our organization is migrating to Windows 7 from Vista. One of my migrated users got an error message that displayed a partial local folder (C:\Users\(username)\...\A100203.doc) during the copy. Does the CopyFile function cache a local copy of the document when it is copying from one network folder to another network folder or is it a direct write? I have never seen this error before and the application has been running for years on Win95, Win 98, Win2000, WinXP and Vista.
Windows.CopyFile does NOT cache the file on your hard drive... instead, it instructs Windows to handle the copying of the file itself (rather than you managing the streams in your own program). The output file buffer (destination) is opened, and the input buffer simply read and written. Essentially this means that the source file is spooled into system memory, then offloaded onto the destination... at no point is an additional cache file created (this would slow file copying down).
You need to provide more specific information about your error... such as either the text or an actual screenshot of the offending error message. This will allow people to provide more useful answers.
The user that launches the copy will require read access to the original and write access to the target, regardless of caching (if the user has read access to the file, then the file can be written to a local cache, so caching/no-caching is irrelevant).
It's basic security to disallow someone to be able to copy files/directories among machines just because the security attributes between the machines are compatible.
There's little else to say without the complete text of the error message.

Making a copy of an ASP.NET MVC website on the same machine - catastrophy?

I wanted to run (using Cassini) two copies of my web application from the same computer - not unreasonable (or so I thought!). One using port 80, the other using port 81. So I did the following:
Stopped Cassini and SQL Express
Copy and paste of the site root folder (and renamed it)
Opened Cassini explorer and setup a new site on port 81 and pointed it to the copied location
Changed the web.config of the copied site so that the connection string used "Database=NewAlias" because SQL Express cant attach two databases with the same alias.
Started Cassini and SQL Express again
When I browsed to the NEW site, the first thing that comes up is:
Unable to open the physical file
"C:\site1\App_Data\db_log.ldf".
Operating system error 32: "32(The
process cannot access the file because
it is being used by another
process.)". Cannot create file 'C:\site2
\App_Data\db_log.LDF' because
it already exists. Change the file
path or the file name, and retry the
operation. Cannot open database
"NewAlias" requested by the login. The
login failed. Login failed for user
'NT AUTHORITY\SYSTEM'. File activation
failure. The physical file name
"C:\site1\App_Data\db_log.ldf" may be
incorrect.
Its trying to open the mdf from the OLD location (even if the web.config specifies the exact mdb path to the new location) but trying to create a log in the NEW location. Then to top it all off, drops the hint that it cannot access the ldf from the OLD location, or maybe cant log into it.
Well done Microsoft and your team once again for some truly intuitive errors! Can anyone help?
I don't think you can just copy a live database via the files. If you detach it first, then copy it, you can then reattach (with sp_detach_db) it by mounting the files as a new database.
sp_detach_db OldDb
Then copy the folder, then reattach (with sp_attach_db) the db files as a new database.
sp_attach_db NewDb, "C:\copy of site\App_Data\db_data.mdf", "C:\site1\App_Data\db_log.ldf"
Another big problem that sometimes occurs when doing this kind of thing (and did in the scenario above which is vaguely eluded to by the error message) is that although the copied MDF file is being used, its still linked to the original LDF (log file). You can run this command to get a list of which files are being used for a connected instance:
sp_helpfile
Which will give you something like this as a response:
name fileid filename filegroup size maxsize growth usage
=========================================================
db 1 C:\site2\App_Data\db.mdf PRIMARY 24192 KB Unlimited 1024 KB data only
db_log 2 C:\site1\App_Data\db_log.ldf 78080 KB 2147483648 KB 10% log only
You can see from the output that the log file is being shared with the old database which obviously will cause issues, so you can change it to point to the copied log file as follows:
ALTER DATABASE NewAlias MODIFY FILE (NAME = db_log, FILENAME='c:\site2\App_Data\db_log.ldf')

Resources