I write some Applescripts that are gonna be deployed on machines set to different languages. I just realised that when I, for example, is waiting for an application to open a window (e.g., a Save/Open dialog) my scripts fail because on systems set to other languages these windows are not called Save or Open anymore, but rather have a translated name.
How do I handle this? Do windows have "universal base name" I can look for rather than the name I Accessibility Inspector shows? And I guess there are other strings that also are translated that I might need to access (menus, menu commands and so on) - my problem is not limited to just Open/Save dialogs.
AppleScript supports NSLocalizedString (localized string). You need to refer to and pull out the strings from the corresponding framework bundles.
For example:
set finderPath to path to application "Finder"
(localized string "A16" in bundle finderPath)
The result is:
in English: You can’t undo this action.
in German: Diese Aktion kann nicht widerrufen werden.
localized string has two optional parameters:
from table : The name of the strings file excluding the “.strings” suffix (default is “Localizable”)
in bundle : An alias or file reference to the bundle containing the strings file (default is the current application/script bundle)
Related
I am a 3rd party, and I would like to start an 1st party application and virtualize somehow a document folder that I would decide the location.
The first application would not touch the real 'my document' folder but instead save the file in a location I would set.
I don't want to change the registry entries for the personal folders, I want it just for this application.
I did some research but didn't find anything like that. Is that possible without a virtual machine? I would try to work in VB6, I want to test something on xp and win7. It's about a game redesign, and I would like the person to be able to have my program, and the original game installed on the PC without the configuration folders in 'my document' colliding.
I should mention that I cannot pass parameters to it because I am launching the 1st party application through a 2nd party executable already.
Thank you!
Yanick
Of course you can, with a text file (or a program). MS made it easy.
Here is someone quoting my post, who is quoting Raymond Chen directly,
http://www.pcreview.co.uk/threads/re-create-system-folder.522854/
Creating Shell Extensions with Shell Instance Objects
Raymond Chen
Microsoft Corporation
February 2000
Summary: A traditional shell namespace extension requires the implementation
of a COM in-process server. Shell instance objects allow you to create
simple shell extensions without having to write a single line of code. This
article describes how shell instance objects and shell command objects can
be used to easily deploy simple shell extensions. (5 printed pages)
Contents
What Is a Shell Namespace Extension?
What Is a Shell Instance Object?
Shell Objects That Can Be Created as Shell Instance Objects
How About an Example?
Shell Command Objects
Conclusion
What Is a Shell Namespace Extension?
Shell namespace extensions allow you to create "virtual folders" in the
shell. For example, the Recycle Bin icon on the desktop is not an actual
file system directory, but rather represents a collection of items that is
maintained by the Recycle Bin shell extension.
Details on creating shell namespace extensions can be found in the Platform
SDK section of the MSDN Online Library
(http://msdn.microsoft.com/library/psdk/shellcc/shell/shell_adv/namespace.ht
m).
Writing a shell namespace extension can be quite an ordeal. Fortunately, the
shell provides an easy way to create certain types of simple shell namespace
extensions, as this article will show.
What Is a Shell Instance Object?
A shell instance object is a special kind of shell extension provided by the
shdocvw.dll component. Whereas a traditional shell extension requires a DLL
to implement the object, a shell instance object retrieves everything it
needs to know from the registry.
How the shell creates a shell instance object
1.. The shdocvw.dll component is loaded by virtue of being registered as
the InProcServer32 for the shell instance object.
2.. When shdocvw.dll is asked to create an object it does not otherwise
recognize, it checks the registry key for a subkey named Instance. If found,
it reads the CLSID value of that subkey and passes that CLSID to the
CoCreateInstance function. (For lack of a better term, let's call this the
"host" object.)
3.. Next, shdocvw.dll looks for a subkey of Instance named InitPropertyBag
or InitStream. If found, it then creates an IPropertyBag or IStream
(accordingly) based on the contents of the registry key and passes it to the
IPersistPropertyBag::Load or IPersistStream::Load method (accordingly).
4.. Finally, shdocvw.dll returns the now-initialized host object as the
shell instance object.
Shell Objects That Can Be Created as Shell Instance Objects
There are two shell objects that support being the host object of a shell
instance object, namely the Shell link object and the Shell folder shortcut
object.
Both of these objects support the IPersistPropertyBag interface, so you can
use the InitPropertyBag method of initializing them. (It so happens that
both objects also support IPersistStream, but initializing a shortcut from a
registry stream is much more cumbersome.)
The property bag you provide in the registry describes the target of the
shell link or shell folder shortcut object. There are three supported forms
for this property bag.
Targeting a shell special folder
InitPropertyBag
TargetSpecialFolder=REG_SZ:"<special folder number>"
Notice that this is a REG_SZ registry value even though it represents an
integer. Both decimal and hex notation are supported.
Targeting a directory inside a shell special folder
InitPropertyBag
TargetSpecialFolder=REG_SZ:"<special folder number>"
Target=REG_SZ:"<subdirectory name>"
The subdirectory name can contain embedded backslashes.
Targeting a directory by explicit path
InitPropertyBag
Target=REG_SZ:"<full path to target directory>"
How About an Example?
Here's a copy of the registration that creates the Fonts folder icon in
Control Panel:
HKEY_CLASSES_ROOT
CLSID
{D20EA4E1-3957-11D2-A40B-0C5020524152}=REG_SZ:"Fonts"
InfoTip=REG_SZ:"Displays and manages fonts on your computer"
DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\system32\main.cpl,9"
InProcServer32=REG_EXPAND_SZ:"%SystemRoot%\system32\shdocvw.dll"
ThreadingModel=REG_SZ:"Apartment"
ShellFolder
Attributes=REG_DWORD:0x60000000
WantsFORPARSING=REG_SZ:""
Instance
CLSID=REG_SZ:"{0AFACED1-E828-11D1-9187-B532F1E9575D}"
InitPropertyBag
TargetSpecialFolder=REG_SZ:"0x0024"
Target=REG_SZ:"Fonts"
Because {D20EA4E1-3957-11D2-A40B-0C5020524152} is registered in the Control
Panel namespace, a Fonts folder shortcut is installed in Control Panel.
Let's go through this registry key step by step.
a.. The GUID {D20EA4E1-3957-11D2-A40B-0C5020524152} was generated by
running the uuidgen program found in the Platform SDK. Of course, when you
create your own instance objects, you should run uuidgen and use your own
GUID. The name of the icon as it appears in the namespace is also provided
here.
b.. The optional InfoTip string is displayed when the user hovers over the
icon.
c.. The DefaultIcon string provides the name and icon index for the icon
to display for this item.
d.. The InProcServer32 key must be set to the shdocvw.dll file, and the
threading model must be set to Apartment.
e.. The ShellFolder key sets the Attributes to a collection of SFGAO_
values, which we wish to apply to the folder shortcut. The SFGAO_FOLDER flag
must always be set. Because the target is a file system folder, the
SFGAO_FILESYSTEM flag is also set in the Attributes, and the WantsFORPARSING
value is set to an empty string. (If the target is not a file system folder,
the WantsFORPARSING value should not be created.)
f.. The Instance key sets the CLSID value to the string representation of
CLSID_FolderShortcut. This indicates that the object instance should create
a folder shortcut.
g.. The InitPropertyBag key indicates that the folder shortcut will be
initialized with the IPersistPropertyBag interface. The two values inside
the property bag specify that the target is the subdirectory "Fonts" in the
special folder 0x0024, which is CSIDL_WINDOWS.
Shell Command Objects
Another type of shell extension object is an icon that when double-clicked
runs a command. This, too, can be created without having to write a COM
server. For example, here is a command object that is used by the My Network
Places folder:
HKEY_CLASSES_ROOT
CLSID
{D4480A50-BA28-11d1-8E75-00C04FA31A86}=REG_SZ:"Add Network Place"
InfoTip=REG_SZ:"Connects to shared folders, Web folders, and FTP
sites."
DefaultIcon=REG_EXPAND_SZ:"%SystemRoot%\System32\netplwiz.dll,-107"
ShellFolder
Attributes=REG_DWORD:0x00000000
Shell
Open
Command=REG_EXPAND_SZ:"rundll32 ..."
Most of this registry key should look familiar, so I will only highlight the
differences from shell instance objects:
a.. There is no InProcServer32 key.
b.. The Attributes of the ShellFolder key should omit the SFGAO_FOLDER
flag because this item is not a folder.
c.. Instead of an Instance key, we have a Shell key, which has the same
structure as a progid key. The "Open" verb is the default action for
double-clicking. You can also create other verbs, which will appear on the
context menu. For example, the Internet Explorer icon creates a custom verb
called "Open Home Page."
Details on the structure of the Shell key can be found in the Platform SDK
section of the MSDN Online Library under the topic heading "Extending
Context Menus"
(http://msdn.microsoft.com/library/psdk/shellcc/shell/shell_basics/context.h
tm).
Conclusion
Shell instance objects and shell command objects allow you to deploy simple
shell extensions with a minimum amount of work. For example, you might
create a command object in the Control Panel folder called "Troubleshoot,"
which runs a troubleshoot program. Or you might create a shell instance
object that hosts a folder shortcut to a collection of system administrative
tools on a shared network server. Shell instance objects and shell command
objects allow you to easily deploy these types of shell extensions.
My solution was to search the executable with a hex editor and manually edit it to another folder. Of course I had to choose a folder with less or equal number or character in the path.
Thank you all.
I know how to list all window titles in Windows, for example using Python via the Win32 API. Or eventually I could write it in C/C++ directly.
How do I accomplish this for Mac OS X? It doesn't necessarily have to be in Python, and it doesn't have to be cross-platform. Preferably it would run without requiring any additional downloads (like an applescript file or a bash file using included commands only), but that's not required.
Probably the simplest way of doing this "with no additional downloads" is to use AppleScript:
tell application "System Events"
get name of every window of every process
end tell
Since the Applescript syntax is pretty obtuse, the equivalent Javascript is:
var SE = new Application("System Events");
SE.processes.windows.name()
This will return a structure of the form:
[[], [], ["Stack Overflow"], ["iTunes", "MiniPlayer"], ...]
where each array entry represents one running application, and each string within those arrays represents one window. Empty arrays indicate applications with no open windows.
(Note that this Javascript must be run in Script Editor, not in a web browser. Components of the Scripting Bridge, including System Events, are not available from web browsers.)
I have a legacy app (minimally ported from Mac System 7 to Carbon to Cocoa) where users are reporting that the kMDItemKind metadata, as reported my mdls, of text files saved by the app seem to be set to "Microsoft Excel 97-2004 workbook". The legacy file creator and type should have been set to 'cBaS' and 'TEXT' (as was registered with Apple in ye ole ancient days), and the legacy file extension is ".bas".
What sets the kMDItemKind metadata of saved files under Mac OS X?
How do I make sure that the kMDItemKind is set correctly when saving these text files, so that my app will open them?
You can't directly set the kMDItemKind of a file. It is derived from other metadata. The file type code 'TEXT' is quite generic. The creator code is ignored these days. The file extension is probably what the system is relying on.
Unfortunately, in your case, you have multiple apps which handle .bas files. Which of those the system picks is somewhat arbitrary and subject to change. Launch Services is assigning the kind based on which would actually be used and how that app defines the document type or UTI that's matching the file extension.
Normally, you should leave the association of files with specific applications to the user. If they want to change it, they can do so with Always Open With accessible in the Finder's File menu or context menu when the Option key is held down. Or they can use the Get Info menu.
Your best bet would be to switch to using a more-likely-to-be-unique file extension
I need to write a shell extension for a small context menu.
unfortunately i reused the code available in open source which uses .net 4.0
now the problem is the requirement is I shud not use .NET 4.0.
Instead is there a way where in I can make an entry in the registry so that the shell extension pops out
My requirement is ....
1. The shell extension context menu should display only on .txt, .csv, .xls files.
2. Upon click of shell extension I need to start a different process, by passing the full name of the file on which we click as parameter to the process.
If you just want to add items to the context menu for certain file types, and in response launch an external application, you don't need to write a shell extension. Registry entries are enough to express this.
As the http://www.jfitz.com/tips/rclick_custom.html article you linked to says, for each file type you want to act on, you need to add a new registry key under the Shell subkey, then create a subkey called command, whose value is the name of the application to launch.
To pass the name of the file you clicked on to this external application, add "%1" to the command. Include the quotes, so that if the file's name contains spaces, it will still be treated as one token by the receiving program.
Explanation:
I don't remember about Linux and I don't know about OS X, but in Windows you can right-click a file and select a program to open it. But how does the OS know exactly how to make the program open it? Does it keep track of the "Open file" dialogs the program has? Does the developer have to specify a special event handler or something for these cases?
For Windows, the answer is in the registry. If you're comfortable reading the registry, run regedit.exe on your Windows machine.
Under HKEY_CLASSES_ROOT, you will see a key list of all file types, .doc, .txt, etc. Each of these keys contains a key called "OpenWithList" or "OpenWithProgIds". An application may have a registered "ProgId", also found under HKEY_CLASSES_ROOT, and it can register it's ProgId to the file types it wants to handle in OpenWithProgIds. Otherwise it registers itself in OpenWithList.
In response to the comment to the first answer (cos I don't have enough rep to comment):
You're thinking of DDE, which is a near-enough deprecated technology. The Windows shell executes the application with the selected file as the first parameter.
The Windows Explorer remembers your previous "Open With..." choices based on file extension in the following key:
HKCR\.ext\OpenWithList
Next time you right-click the file, it looks there and build a list of programs you have previously used to open a particular file type.
Say it finds a key named "myapp.exe". It then looks up the application here:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Applications\myapp.exe
fetches the info where the application is installed. And it goes here:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\myapp.exe
follows the GUID stored there to find out the display name of the application.
To add to the fun, the primary associated application is in the list as well, also everything in the OpenWithProgIds key and everything in:
HKEY_CLASSES_ROOT\*\OpenWithList
as well as their respective HKEY_CURRENT_USER counterparts.
The resulting list of applications is then made unique, sorted and displayed. On selection the file is started like any other file you click on - i.e.:
C:\path\to\myapp.exe "C:\path\to\the\file.ext"
http://windowsxp.mvps.org/OpenWith.htm
File associations are stored in the Registry in: HKEY_CLASSES_ROOT.
You can manage them graphically by using Windows Explorer: (WinXP)
Click Tools/Options/File Types
Or with the "Default Programs" applet in Control Panel. (Vista)
Just for some nostalgia the rather brilliant Acorn archimedes had a much better system with each file type having a unique type number, with a manufacturer and application code (rather like a MAC address) which was written with the file.
This means you can have different files all called .bak opened by the correct application - unlike the windows case where a new installed app steals the ownership of every exiting file of that type. Autocad is especialy bad for this, registering about 20 file types.
The operating system runs the specified program sending as parameter the path of the file to open.
For example, in C#, if you want to know which file the operating system wants you to open you'll need to do:
class Program
{
static void Main(string[] args)
{
if (args.Length == 1) //The OS wants me to open a file
openSomeFileJustBecauseTheOSWantsIt(args[0]);
}
}