Namespace shell extension like zip - explorer

I want to create a namespace shell extension which allows users to browse content of my archives directly in Windows Explorer (like zip files). I have some experience in creation of NSE and it is not problem for me to implement all nessesary interfaces. The only thing I dont understand how to register such NSE in Windows registry. And how can I force Explorer to open my archive programmatically from context menu shell extension (in new or in the same window).
UPDATE
I examined .zip registry keys and tried to register my NSE with the same way.
My extension is .0003. I created the following keys:
[HKEY_CLASSES_ROOT\.0003]
#="TCIntegrationPack.64.TWCXNamespace"
[HKEY_CLASSES_ROOT\TCIntegrationPack.64.TWCXNamespace]
#="test only"
[HKEY_CLASSES_ROOT\TCIntegrationPack.64.TWCXNamespace\CLSID]
#="{B1BE3C6B-25E2-47DE-8AB9-878FCA3CD01A}"
[HKEY_CLASSES_ROOT\TCIntegrationPack.64.TWCXNamespace\Shell]
[HKEY_CLASSES_ROOT\TCIntegrationPack.64.TWCXNamespace\Shell\open]
"MultiSelectMode"="Document"
[HKEY_CLASSES_ROOT\TCIntegrationPack.64.TWCXNamespace\Shell\open\Command]
#="%SystemRoot%\\Explorer.exe /idlist,%I,%L"
"DelegateExecute"="{11dbb47c-a525-400b-9e80-a54615a090c0}"
[HKEY_CLASSES_ROOT\CLSID\{B1BE3C6B-25E2-47DE-8AB9-878FCA3CD01A}]
#="TCIntegrationPack.64.TWCXNamespace"
[HKEY_CLASSES_ROOT\CLSID\{B1BE3C6B-25E2-47DE-8AB9-878FCA3CD01A}\InprocServer32]
#="F:\\Delphi\\Projects\\TCIntegrationPack\\Win64\\Debug\\TCIntegrationPack.64.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{B1BE3C6B-25E2-47DE-8AB9-878FCA3CD01A}\ShellFolder]
"Attributes"=dword:08000000
For testing I run the following command:
explorer.exe /root,{B1BE3C6B-25E2-47DE-8AB9-878FCA3CD01A},"f:\1.0003"
And I see in logs the following:
TWCXNamespaceRootFolder is created
TWCXNamespaceRootFolder.QueryInterface IShellFolder out Result=S_OK
TWCXNamespaceRootFolder.IShellFolder.BindToObject started
TWCXNamespaceRootFolder.IShellFolder.BindToObject in AItemIDList=F:\
TWCXNamespaceRootFolder.IShellFolder.BindToObject in AReserved=0000000000000000
TWCXNamespaceRootFolder.IShellFolder.BindToObject in AIID=IShellFolder
TWCXNamespaceRootFolder.IShellFolder.BindToObject out Result=E_NOTIMPL
TWCXNamespaceRootFolder.IShellFolder.BindToObject finished
TWCXNamespaceRootFolder is destroyed
Shell request IShellFolder interface of parent folder of my file. Is it normal? Where is my mistake?
UPDATE 2
The problem is solved. It is necessary to add additional registry key
HKCR\CLSID\{extension CLSID}\Implemented Categories\{00021490-0000-0000-C000-000000000046}
After this Explorer uses my extension correctly. Some detains can be found here.

Related

Use File System Access API in Chromium Embedded Framework

My program uses CEF(Chromium Embedded Framework) to implement a simple browser component. I want to use the File System Access API in the CEF to read and write local files but it occurs some problems. https://mburakerman.github.io/file-system-access-api-demo/ is the test page I use to experiment the File System Access API. I used Chrome at first and Chrome behaved well, it read and wrote local files normally. Then I compiled the CEF(The verstion is 96) project and used the cefclient to test whether the CEF also worked well but it could not. CEF could read the local files right but when I clicked the "Save changes" button there was no response and it failed to write the local file I choosed before either. After that I ran the source code of Chromium and CEF to compare the differences in File System Access API. When I was going to write the local file the code of Chromium and CEF ran to the same position as the picture shown below.Chromium and CEF ran to the same position when wrote local files Both of them entered in the DoRequestPermission function. It was very strange that the current_status of Chromium was "ASK" but CEF was "DENIED". The current_status value in CEFThen I checked the stack it showed that the status of the file was initialized at the message dispatch time and I could not find where the status was initialized.The stack of CEF when using File System Access API enter image description hereI wonder why the status in Chromium is "ASK". Does it use some specific command lines or some other methods?

Unreasonable amount of "Files In Use" during WiX installation process

I used WiX to build an installer (MSI) for an application, which works fine, except for this unreasonable amount of "applications that are using files that need to be updated by this setup":
This happens for some users some times, and I don't quite understand why this happens, and how to fix it.
I don't see a reason that the installation process of my application would conflict with all of these applications, and I'm not sure how to investigate it further.
My application is a standalone desktop application - not any add-on or something that interacts or depends on any of the applications listed.
The steps my installation process does:
Check that .Net framework 4.0 CP is available (exit if not).
Install the application under Program Files[Company][Product] (including my exe, my DLL, 2 third party DLL's that I bundle)
Install MS Visual C++ Runtime Redist 14.0 if needed
Add Start menu items for the application (launch & uninstall shortcuts)
Custom action for creating a scheduled task that starts my application on user logon as admin (the application runs in the tray as admin).
Custom action for starting the application after setup finishes (if checkbox is checked in last dialog).
Any advice on how to fix this, or at least investigate what causes this, will be appreciated :-)
Does it happen only when you run the installer and your desktop application is already running?
To investigate this further, best place to look at is your log file. The log file will have the details about the file which is being held by the other process, something like:
Info 1603. The file C:\...\abc.exe is being held in use by the following process: Name: xyz, Id: 19010, Window Title: 'xyz'. Close that application and retry.
Info 1603. The file C:\...\abc.dll is being held in use by the following process: Name: xyz123, Id: 9243, Window Title: 'xyz123'. Close that application and retry.
Once you determine the actual file being used by those other process, then it will help you figure out what the root cause is. Basically the INSTALLVALIDATE windows installer action determines if one or more files to be overwritten or removed are currently in use by an active process. An entry is added to an internal FilesInUse table if any file is overwritten or removed while it is open for execution or modification by any process during File costing. The FilesInUse table contains columns for the name and full path of the file. When the InstallValidate action executes, the installer queries the FilesInUse table for entries and determines the name of the process using the file. The InstallValidate action adds one record to the ListBox user interface table for each unique process identified by this query.

Can I configure a WinSCP instance to always run in the background, keeping a remote directory up to date?

I like using WinSCP for keeping a remote directory up to date, but it locks up the rest of the interface while in use. Is there any way I can configure WinSCP to run on startup (in the background) and keep a certain remote directory up to date with a local copy without impacting the rest of WinSCP's interface?
You can run two instances of WinSCP. One for keeping remote directory up to date, the other for an interactive use.
You can have WinSCP automatically start keeping remote directory up to date. There are two ways, GUI mode and scripting.
GUI mode:
C:\path_to_winscp\WinSCP.exe session_name /defaults
/keepuptodate // C:\local_path /remote_path
(Line break added for readability. The /defaults make WinSCP skip the options dialog.)
For details, see https://winscp.net/eng/docs/commandline
This way you cannot make WinSCP open in the background. You have to manually press the Minimize button.
Scripting mode:
C:\path_to_winscp\WinSCP.exe /console /command "option batch abort"
"open session_name" "keepuptodate C:\local_path /remote_path"
(Line break added for readability.)
For details, see https://winscp.net/eng/docs/guide_automation
If you store this command to a shortcut, you can set it's Run property to Minimized.
For both modes, you can store the command to a shortcut and move it to C:\Users\username\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup to have it automatically started with Windows.
Minimizing to a tray:
Minimizing to a tray is a global preference option:
https://winscp.net/eng/docs/ui_pref_window
If you do not want to enable it globally (it would apply even to the WinSCP instance for an interactive use), add this to the command-line:
/rawconfig Interface\MinimizeToTray=1
See Raw configuration.

Error in registering COM server from bat file lauched from RunOnce

I am currently working on my product installation in Windows XP 64-bit machine. I am trying to register my COM modules as part of installation. I am doing this by adding an entry in 'RunOnce' (registry) key to launch a bat file and registration is done from that bat file.
All my COM dlls are registered correctly but two of the COM servers (.exe) showing error that it failed to load one of its dependency dll. But the same dll is statically linked with another COM server and this server registered successfully !
And surprisingly running the same bat file directly(double clicking on it) doesn't generate any errors and its works fine for all assemblies!. I have checked this in couple of my test machines only of the machines showing this behavior. Unfortunately that't the customer tool machine.
Its not dependency dll not available issue. Because after registering all files by directly running the bat file, I could reproduce this again by adding a key in RunOnce manually and restarting the machine.
Additional info, I am accessing this machine remotely via logmein.
Exact error message: "This application has failed to start because XXX.dll was not found. Re-installing the application may fix this problem".
This XXX.dll is not available in the same path but its in another folder and its path is available in path variable.
bat file content is;
"C:\WINDOWS\system32\regsvr32.exe" RemoteControlHandler.dll
"C:\WINDOWS\system32\regsvr32.exe" ProcPgmHandler.dll
"C:\WINDOWS\system32\regsvr32.exe" GEM300Handler.dll
"C:\WINDOWS\system32\regsvr32.exe" ICEScreenAdapter.ocx
HIB.exe /regserver //Throws error
JobManager.exe /regserver
Cim300Adapter.exe /regserver
GemEquipmentCtrl.exe /regserver //Throws error
Hope this information is enough for experts, feel free to ask if you need any additional information.
Nixon

Detect file in use by other process

On windows and such I used to use a trick to find out of a file is currently in use (written specifically).
I use to open the file for writing and if it failed most likey another process is busy accessing it.
Sadly these trick (using C OPEN with exclusive lock for writing) doesn't work on my Mac. While my curl in a terminal is still writing my -fileBusy() check fails.
fcnt call on the fd with F_GETLK doesn't reveal any locking as well.
Is there any chance for me to detect if a file is in use by another process?
Ps> listening for fsevents can't be done because my app launches after the is created by the other app / process.
Apple confirmed via email that the solution described in the link below is a valid one and not considered a private API.
More information:
http://lists.apple.com/archives/cocoa-dev/2010/May/msg01455.html
You could try running the following shell command using NSTask:
lsof -Fc path/to/thefile
That will give you the process ID and name of any process(es) that have thefile open.