How can my Windows application handle a subdomain or path URI? - winapi

My Windows desktop application handles a specific URI scheme, let's call it myscheme:, so URLs like myscheme://what/ever open my app. We set that up by creating a registry key and several values under HKEY_CURRENT_USER\Software\Classes\myscheme. (It's an app that installs per-user without requiring elevation, thus the use of HKEY_CURRENT_USER.)
I would also like to be able to handle http: and https: URLs in a specified subdomain or path, such as http://mysubdomain.example.com/what/ever. Android provides a way to do this; can I do it in Windows?
I don't need a working example (I'm a fairly experienced Windows developer). All I'm looking for, if the capability exists, is a pointer to any relevant registry key or API name/docs on MSDN or elsewhere - I can take it from there. Thanks!

Related

classic asp create text file on webserver: error 800a0034 Bad_file_name_or_number

I have a classic asp page in VBS and I am trying to create a file on the web server with the following code.
Set fso = CreateObject("Scripting.FileSystemObject")
Set file1 = fso.CreateTextFile("\\localhost\inetpub\wwwroot\cs\batch\123456dirs.bat", true)
This returns the following error:
|666|800a0034|Bad_file_name_or_number
Line 666 is the CreateTextFile line.
According to the Microsoft docs, this means that I'm trying to create a file with an invalid filename. Then it explains the rules for filenames and mine appears to be perfectly valid.
Any suggestions or ideas on how I can further troubleshoot this?
first thing to check to make sure your users have access to the folder. Assuming you're not using windows authentication, make sure IUSR account has write access to the folder.
second, unless inetpub is set up as a share to folder, you're syntax won't work. if the root of your website is located in the CS folder, you can do something like:
Set file1 = fso.CreateTextFile(Server.MapPath( "/cs/batch/123456dirs.bat" ), true)
The createtextfile() function runs on the web server but in the context of the local server itself. Simply put, any path you give it must resolve as if you were logged on to a windows desktop on the server and tried to CD to that path.
The format \localhost... is a UNC path. See this question for a discussion about UNC paths and windows. Unless you know for sure that there is a UNC path mapped for \localhost then that is probably your issue. You may be making the assumption the \localhost will be a reasonable path to use, but as I said unless you know for sure it is available then this is an invalid choice.
Lastly, if you decide to set up a share for \localhost, you will be getting in to some interesting territory around the user context that the web server operates in. You see you will have to set up the share for the IIS user that is configured as the run-as identity for IIS, so you will need to know that and create the required config to give that user the share.
If it were me, I would switch to using a standard windows path, although even then you need to appreciate the run-as user context and security config, etc.

Windows: Register URI-Scheme for specifically formatted http-URL

I've found a lot on this page on how to register a certain URI-scheme to open using a particular application in windows.
All Q & A which I've found cover creating an own protocol for this purpose which which is unique for the application which should be registered.
My question is: Is there a way to open usual http/https-Links which contain a certain pattern/format using application A, instead of opening all http/https-links with the browser?
Example: I want, that all links which match the format http://*.domainX.com/* or http://*.domainX.com/*, should be opened using my own application instead of the browser.
Thanks in advance!
On Windows you can try Registering the Application Handling the Custom URI Scheme
To register an application to handle a particular URI scheme, add a
new key, along with the appropriate subkeys and values, to
HKEY_CLASSES_ROOT. The root key must match the URI scheme that is
being added.
Let me know if this helps

URI scheme launching

I've been given a task to create a protocol similar to callto:, that - upon clicking on a link with it - would automatically launch an installed aplication.
I followed the microsoft guide on how a scheme should look like.
My scheme looks like this:
HKEY_CLASSES_ROOT
slican
URL Protocol = ""
DefaultIcon (Default) = "C:\Users\Okabe\Desktop\slican\SlicanP.exe,1"
shell
open
command (Default) = "C:\Users\Okabe\Desktop\slican\SlicanP.exe" "%1""
I thought that was all and tested it with
test link
test telephone link
There was no reaction whatsoever. Internet Explorer asked me if I want to search for a program that can open the content and Chrome responded with nothing, as if I clicked javascript:void(0).
How to get that worked?
Thank you for your help!
The registration you show works perfectly fine for me when I try it on Windows 7. The local app I registered in place of SlicanP.exe ran fine when I invoked a slican: URL from the Start | Run menu, and from within the address bar of Windows Explorer. So the registration works.
Do be aware that Internet Explorer runs in a lower integrity security context, so it may not have rights to run local programs. When I tried to click on an HTML link to a slican: URL, or type a slican: URL in the address bar, IE had trouble executing the local app (even after prompting for permission). I had to run IE as an administrator, then the local app ran just fine.
Also, you really should not be creating a HKEY_CLASSES_ROOT\slican key directly. Create a HKEY_CURRENT_USER\Software\Classes\slican (current user only) or HKEY_LOCAL_MACHINE\Software\Classes\slican (all users) instead. Refer to MSDN for more details:
HKEY_CLASSES_ROOT Key
Merged View of HKEY_CLASSES_ROOT
Update: Since it works in Windows 7, Microsoft probably changed how URL schemes are registered in Windows 8. For instance, phone/store apps use URI activation:
URI activation (XAML).
URI activation (HTML)
The documentation says there are two ways to register a custom URI scheme:
Internet Explorer uses two mechanisms for registering new pluggable protocol handlers. The first method is to register a URI scheme name and its associated application so that all attempts to navigate to a URI using that scheme launch the application (for example, registering applications to handle mailto: or news: URIs). The second method uses the Asynchronous Pluggable Protocols API, which allows you to define new protocols by mapping the URI scheme to a class.
You are doing the first. Try using the second instead.
However, I just noticed that "Asynchronous Pluggable Protocols" is listed on MSDN in the "Legacy APIs" section, and it has the following note:
Third-party protocol implementations won't load in Windows Store apps using JavaScript, or in the Internet Explorer in the new Windows UI.
So it may or may not work in Windows 8.
Update: I just found this:
Guidelines for file types and URIs
In Windows 8, the relationship between apps and the file types they support differs from previous versions of Windows.
Walkthrough: using Windows 8 Custom Protocol Activation
The file type and protocol association model has changed in Windows 8. Apps are no longer able to programmatically set themselves as the default handler for a file type or protocol. Instead, now the user always controls what the default handler is for a file type or protocol.
Your app can use existing protocols for communication, such as mailto, or create a custom protocol. The protocol activation extension enables you to define a custom protocol or register to handle an existing protocol.
Also have a look at this:
Setting mailto: protocol handler programmatically in Windows 8
And this:
Default Programs
if you go to C:\Users\\AppData\Local\Google\Chrome\User Data
You can edit the Local State file
Search for protocol_handler
The syntax here is a key value pair. I usually copy two mailto: and make sure that you set your protocols to false. This will mean that chrome will treat your new protocols as URI_Handler events
If you have troubles with configuring custom URI scheme, you can compare your own configuration with existing one. For example, "HKEY_CLASSES_ROOT/mailto" - most likely you have it already in your system.

Implementing my own protocol and using it through my browser

I want to create a new protocol so that I can view the data retrieved through the protocol in the browser.
For example, I want to be able to go to myprotocol://www.filepath.com/img.jpg and view the image.
Where myprotocol is defined by myself.
I have read about registering application handling here:
http://msdn.microsoft.com/en-us/library/aa767914%28v=vs.85%29.aspx
with this it is possible to run a desktop exe that receives the url I am trying to access. How would I return the retrieved jpg to the browser for viewing, so that it behaves like a normal protocol, such as http?
Thanks
That registration will allow you to bind an application to the uri, so if launched through windows explorer (including "Run") and from command line, then the app is launched and the uri passed to it as an argument (much like if you double-click a file, the default app for it is launched and the path to the file passed).
For example, your "default" browser will have http:// associated with it in this way.
It is still up to the application itself to have its own handling of the URI when it is passed as an argument. If you want to make a browser handle your new protocol, you will have to write an extension/plugin/add-on/whatever-that-browser's-makers-call-it to add further functionality to the browser. This is a separate job for Firefox, IE, Chrome, Konqueror, Chromium (well, at least it might be sharable with Chrome), etc. with separate APIs to deal with.

Launching a registered mime helper application

I used to be able to launch a locally installed helper application by registering a given mime-type in the Windows registry. This enabled me to allow users to be able to click once on a link to the current install of our internal browser application. This worked fine in Internet Explorer 5 (most of the time) and Firefox but now does not work in Internet Explorer 7.
The filename passed to my shell/open/command is not the full physical path to the downloaded install package. The path parameter I am handed by IE is
"C:\Document and Settings\chq-tomc\Local Settings\Temporary Internet Files\
EIPortal_DEV_2_0_5_4[1].expd"
This unfortunately does not resolve to the physical file when calling FileExists() or when attempting to create a TFileStream object.
The physical path is missing the Internet Explorer hidden caching sub-directory for Temporary Internet Files of "Content.IE5\ALBKHO3Q" whose absolute path would be expressed as
"C:\Document and Settings\chq-tomc\Local Settings\Temporary Internet Files\
Content.IE5\ALBKHO3Q\EIPortal_DEV_2_0_5_4[1].expd"
Yes, the sub-directories are randomly generated by IE and that should not be a concern so long as IE passes the full path to my helper application, which it unfortunately is not doing.
Installation of the mime helper application is not a concern. It is installed/updated by a global login script for all 10,000+ users worldwide. The mime helper is only invoked when the user clicks on an internal web page with a link to an installation of our Desktop browser application. That install is served back with a mime-type of "application/x-expeditors". The registration of the ".expd" / "application/x-expeditors" mime-type looks like this.
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.expd]
#="ExpeditorsInstaller"
"Content Type"="application/x-expeditors"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller]
"EditFlags"=hex:00,00,01,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller\shell]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller\shell\open]
#=""
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\ExpeditorsInstaller\shell\open\command]
#="\"C:\\projects\\desktop2\\WebInstaller\\WebInstaller.exe\" \"%1\""
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type\application/x-expeditors]
"Extension"=".expd"
I had considered enumerating all of a user's IE cache entries but I would be concerned with how long it may take to examine them all or that I may end up finding an older cache entry before the current entry I am looking for. However, the bracketed filename suffix "[n]" may be the unique key.
I have tried wininet method GetUrlCacheEntryInfo but that requires the URL, not the virtual path handed over by IE.
My hope is that there is a Shell function that given a virtual path will hand back the physical path.
I believe the sub-directories created by IE are randomly generated, so you won't be able guarantee that it will be named the same every time, and the problem I see with the registry method is that it only works when the file is still in the cache...emptying the cache would purge the file requiring yet another installation.
Would it not be better to install this helper into application data?
I'm not sure about this but perhaps this may lead you in the right direction: try using URL cache functions from the wininet DLL: FindFirstUrlCacheEntry, FindNextUrlCacheEntry, FindCloseUrlCache for enumeration and when you locate an entry whose local file name matches the given path maybe you can use RetrieveUrlCacheEntryFile to retrieve the file.
I am using a similar system with the X-Appl browser to display WAML web applications and it works perfectly. Maybe you should have a look at how they managed to do it.
It looks like iexplore is passing the shell namespace "name" of the file rather than the filesystem name.
I dont think there is a documented way to be passed a shell item id on the command line - explorer does it to itself, but there are marshaling considerations as shell item ids are (pointers to) binary data structures that are only valid in a single process.
What I might try doing is:
1. Call SHGetDesktopFolder which will return the root IShellFolder object of the shell namespace.
2. Call the IShellFolder::ParseDisplayName to turn the name you are given back into a shell item id list.
3. Try the IShellFolder::GetDisplayNameOF with the SHGDN_FORPARSING flag - which, frankly, feels like w'eve just gone in a complete circle and are back where we started. Because I think its this API thats ultimately responsible for returning the "wrong" filesystem relative path.
Some follow-up to close out this question.
Turned out the real issue was how I was creating the file handle using TFileStream. I changed to open with fmOpenRead or fmShareDenyWrite which solved what turned out to be a file locking issue.
srcFile := TFileStream.Create(physicalFilename, fmOpenRead or fmShareDenyWrite);

Resources