Getting working directory on OpenFileDialog - winapi

When you select a number of files on OpenFileDialog you get the working directory path in a structure member of OPENFILENAME but when you select a single file you get the path to filename in that variable member.
Would there be a possible way to get the path first before looping and counting to check the number of files?

Not quite sure what you mean, OpenFileDialog is a .NET class. Assuming native: you can set the OPENFILENAME.lpfnHook member to a callback function. That gives you notifications like CDN_FILEOK and CDN_FOLDERCHANGE. Gives you a preview of what was selected before the dialog closes and a way to cancel it.

Related

NSUserAutomatorTask variables array/list values cannot be parsed by Automator actions

I am using NSUserAutomatorTask to launch an Automator workflow from a macOS app.
I'm passing in variables via the variables property:
https://developer.apple.com/documentation/foundation/nsuserautomatortask/1418099-variables
Inside the Automator workflow I will then use Get Value of Variable actions to grab the variables that were set on the NSUserAutomatorTask and pass the variables to subsequent Automator actions:
Code looks like this: (simplified; I also check that the variables exist in the workflow)
let workflow = try! NSUserAutomatorTask(url: url)
workflow.variables = [
"singleFilePath": "/image1.png",
"multipleFilePaths": ["/image1.png", "/image2.png"],
]
workflow.execute(withInput: nil)
I'm able to print out the variable values in an alert via an Ask for Confirmation action:
The String variable's value is a simple string: /image1.png
The [String] array variable's value is wrapped in parentheses and each item is quoted:
(
"/image1.png",
"/image2.png"
)
I now run the pictured Automator workflow that first gets a variable's value and then attempts to open those Finder items.
The singleFilePath var works. It's passed on to the Open Finder Items action, and that file is opened by the default application.
Passing multipleFilePaths in the same manner does not work. No files are opened. Automator displays the error:
The action "Open Finder Items" was not supplied with the required data.
The action is "Open Finder Items", so there must be some way to pass multiple file paths to this action.
My questions and solutions in order of preference are:
Why is the default variable array/list format not working when passed to the subsequent action? Is there any way to pass or parse the array variable in a compatible format?
Can we use a single Run AppleScript action to reformat the array variable into a format that can be passed to subsequent Automator actions? (I'd like to continue to chain Automator actions rather than run pure AppleScript).
Open Finder Items actions can open an array of items if used in a normal non-variables workflow. And it's seemingly in the exact same format.
As a control to test this, rather than the variable, I'm using the Get Specified Finder Items action.
I then use a View Results action to inspect what is sent to Open Finder Items.
The results are seemingly exactly the same as when I parse the variable:
(
"/image1.png",
"/image2.png"
)
This workflow does correctly run the final action and open the files.
So Open Finder Items should work with the data I'm setting in the variable. I'm unsure why the variable data cannot be opened but manually-picked files can.
I opened a DTS ticket for this issue and received the following response:
I’m sorry to say the engineers working on this have confirmed that yes, it’s a bug, and no, there isn’t a workaround for sandboxed apps. They’ve also noted this isn’t a regression in behavior from previous releases.

How can I open multiple files the same way explorer.exe does? [duplicate]

I am wondering if it's possible to somehow use ShellExecute to open multiple files at once using the default verb handler. For example, if I have multiple mp3 files in a folder, I can select all of them, then right click and select "Play". This will bring up one instance of WMP (which is my default mp3 player) and will add all of the files I selected to the current playlist.
1) Is this accomplished using some standardized ShellExecute behavior?
2) Or is this done by first determining what the default program is and then supplying the list of files as arguments to that executable?
My goal is to be able to take a list of files and open them using the default verb with the default program (ideally without having to dig through the registry first).
I.e. the equivalent of this, but for multiple files:
ShellExecute(NULL, NULL, the_file_to_open, NULL, NULL, SW_SHOWNORMAL);
No, ShellExecute can't do this. Instead, the way to do it is with IContextMenu.
Broadly speaking:
Bind to the parent folder with SHBindToObject
Query for a context menu for the files in question with IShellFolder::GetUIObjectOf
Initialise the context menu with IContextMenu::QueryContextMenu, passing the CMF_DEFAULTONLY flag
Invoke the default command with IContextMenu::InvokeCommand

How can I force QueryFullProcessImageNameW to give me the full form?

I'm enumerating the running processes, and for each process, using QueryFullProcessImageNameW to get the path on disk of the process.
QueryFullProcessImageNameW returns a path like "C:\Program Files (x86)\ALongFolderName\foobar.exe" for most processes.
But for some processes, I get the old 8.3 format instead, like "C:\PROGRA~2\ALONGF~1\foobar.exe'"
How can I always retrieve the long form, as I can see it in File Explorer?
You cannot force the API to return the long form; it simply returns the path that was used to load the corresponding image in the first place.
You can instead call GetLongPathName() to translate an 8.3 name into its long form.

WinAPI function which replaces file but preserves file information

I remember there was a WinAPI function which copied the "date modified" property of the previous file which was replaced with it or something like that? Perhaps anyone can tell me about it?
The problem occured when you used that function very frequently.
This is ReplaceFile (Windows 2000 and up):
The ReplaceFile function combines
several steps within a single
function. An application can call
ReplaceFile instead of calling
separate functions to save the data to
a new file, rename the original file
using a temporary name, rename the new
file to have the same name as the
original file, and delete the original
file. Another advantage is that
ReplaceFile not only copies the new
file data, but also preserves the
following attributes of the original
file:
Creation time
Short file name
Object identifier
DACLs
Encryption
Compression
Named streams not already
in the replacement file
Not too clear exactly what you want, but it seems your after SetFileTime to edit and GetFileTime to copy, combining the two you can do exactly as 'described/wanted'

Pass variable and its contents from workspace to GUI function in MATLAB

I have a variable in the MATLAB workspace and I want to pass the variable name and its contents to a function in my GUI.
How do I achieve this task?
I'm not totally sure what you mean when you say "pass the variable name and its contents", but here's one possible solution. After you pass a set of data to a function like so:
some_function(data); %# Pass the variable "data" to a function
You can get the variable name of the input argument from inside the function using INPUTNAME:
function some_function(inputArgument)
name = inputname(1); %# Will return "data" as the name of the input variable
end
EDIT: As pointed out in a comment by High Performance Mark, the variable inputArgument inside the function will contain the values stored in the variable data in the workspace of the caller.
If this question is related to your other most recent question, then why not build the operation into your GUI? You can use guide to create a pushbutton, and place the code under the callback function.
I am assuming that you have created the figure with GUI using the GUIDE, and that you know the 'Tag' names of the GUI objects.
((1)) Open the figure using the GUIDE, ((2)) Open the Property Inspector for the figure (select the background, the light-gray gridded area of the figure, and double-click over it, to make the Property Inspector for the figure to pop-up), ((3)) Turn the 'HandleVisibility' 'on' (by default, it may be set as 'callback'), ((4)) Save the figure and close the GUIDE, and finally ((5)) set the GUI property values from the MATLAB Console (or "Command Window") using some parameters that are currently available on your workspace.
I hope this helps.
Best,
Y.T.

Resources