windows - create shortcut to printer with powershell - windows

There are various questions and answers on SO explaining how to create a shortcut to the printer queue of a printer using powershell. They all use a shortcut destination like this: C:\Windows\System32\rundll32.exe printui.dll,PrintUIEntry /n Printername.
However, the shortcuts created like this do not have the right-click options like Scan which are visible when right-clicking the printer on the printer & devices page in the control panel. Right-clicking the printer on the Devices and Printers page reveals a Create Shortcut option, which creates a shortcut which has the same right-click options as the original item. (Dragging the printer to the desired destination folder works too)
The properties pages of the shortcuts created a) with powershell b) with the Create shortcut option also look quite different:
Thus, my question is: How do I create a shortcut that is equivalent to the shortcut created when using the right-click option Create Shortcut on a printer on the devices and printers page with powershell?

The correct shortcut does not point to rundll32.exe, it points to the printer in the shell namespace. This target is an item id list, not a filesystem path.
I don't know the native way to do this in Powershell. With P/invoke it would be SHParseDisplayName + IShellLink::SetIDList.
You would probably want to go the reverse way first; on a correct link, get its id list and call SHGetNameFromIDList(...,SIGDN_DESKTOPABSOLUTEPARSING,...). The returned string would look something like ::{GUIDHERE}\::{ANOTHERGUID}\MyPrinterName.

Thanks to Anders for bringing me onto the right track.
You can achieve it like this:
Get a list of all devices and printers:
$shell = New-Object -ComObject Shell.Application
$devices_and_printers = $shell.namespace("::{26EE0668-A00A-44D7-9371-BEB064C98683}\2\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}")
$devices_and_printers.items() | select name,path
Create shortcut:
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$env:userprofile\Desktop\My Printer.lnk")
$Shortcut.TargetPath = ($devices_and_printers.items() | where { $_.name -eq "My Printer Name" }).Path
$Shortcut.Save()

Related

Open folder on portable device with batch file

General goal: create a desktop shortcut to a folder buried the file structure of my phone's SD card (connected via USB). Note, this is on a work computer, so I can't do anything to crazy.
I tried using normal shortcuts to no avail, so I decided to try using a batch if I can't use a shortcut. If using a shortcut is possible or there is a better option than a batch let me know.
Specific question: How can I open a folder using a batch file? I can manually open explorer, paste the address into the bar and go there, so there should be a way to mimic this, but so far my attempts have been unsuccessful.
Attempts:
%SystemRoot%\explorer.exe "Computer\My S4\Phone\Android\data\com.dropbox.android\files\scratch\"
explorer Computer/My S4/Phone/Android/data/com.dropbox.android/files/scratch
start "" "Computer\My S4\Phone\Android\data\com.dropbox.android\files\scratch\"
start Computer\My S4\Phone\Android\data\com.dropbox.android\files\scratch
This is an addition to Andry's answer:
It can be very complicated to get the whole path to an MTP folder like
::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_03de&pid_21e7&mi_00#6&a5ebb37&1&0000#{6ac27878-a6fc-2155-ea85-f98f491d4f33}\{E4FC4EA5-FFFF-FFFF-0000-000000000000}
To get the path do the following:
In Windows Explorer select the folder on the MTP device you want to get the path of.
Open it's context menu and select Copy
Open in Explorer a folder on your PC, open the context menu on a free area and select Paste Shortcut
Now we need a too that can read .lnk files. I have used the tool LECmd. Execute LECmd.exe -f <path to the .lnk file created in step 3>.
You will get a lot of content printed to the console. The interesting part is the Parsing Path next to the end.
In my case it was ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_03de&pid_21e7&mi_00#6&a5ebb37&1&0000#{6ac27878-a6fc-2155-ea85-f98f491d4f33}\SID-{10001,,21003612160}\{E4FC4EA5-FFFF-FFFF-0000-000000000000}
Now we are close, unfortunately the path shown above can not be used because it contains an invalid part: \SID-{10001,,21003612160}. Remove that part and you can open the explorer in that MTP folder using
start "" "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_03de&pid_21e7&mi_00#6&a5ebb37&1&0000#{6ac27878-a6fc-2155-ea85-f98f491d4f33}\{E4FC4EA5-FFFF-FFFF-0000-000000000000}"
There is a way to open an MTP device folder directly in the Windows Explorer window on Windows 7 x64.
Here is steps:
Open Windows Explorer with the My Computer folder, for example:
start "" "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
start "" "shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
explorer "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
explorer "shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
The complete list of GUIDs you can find on the internet, for example: https://www.tenforums.com/tutorials/3123-clsid-key-guid-shortcuts-list-windows-10-a.html
Attach the MTP device and enable File Transfer mode in the device. It must be shown in the My Computer window as a portable device entry.
Drag and Drop the MTP device entry icon to the Desktop.
Open any notepad, for the instance, Windows notepad: Win+R -> notepad
Drag and drop the desktop icon into notepad window.
At the end of the notepad text would be something like:
::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_0e8d&pid_201d&mi_00#7&1084e14&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33} (spaces removed).
You can cleanup the spaces between characters by copy the string into another instance of the notepad and replace them through the Ctrl+H to nothing.
Now you can open the MTP device folder directly:
start "" "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_0e8d&pid_201d&mi_00#7&1084e14&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\<your-local-path-to-folder>"
There is a wait timeout, so the Windows Explorer window might not open immediately.
To generate a shortcut to target folder you can use make_shortcut.vbs script from here: https://github.com/andry81/contools/tree/HEAD/Scripts/Tools/ToolAdaptors/vbs/
For example:
>
make_shortcut.vbs myphonecamera.lnk "shell:::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\\?\usb#vid_0e8d&pid_201d&mi_00#7&1084e14&0&0000#{6ac27878-a6fa-4155-ba85-f98f491d4f33}\SD-card Samsung\DCIM\Camera
Now you can click myphonecamera.lnk to open the folder or use the Windows Explorer:
>
explorer myphonecamera.lnk
Instead of using Computer which is not a device name, try to use \\?\ or \\.\ which both refer to the local computer.

Open some Windows dialogs directly

From my software I'd like to be able to access several Windows dialogs direcly. Basically shortcuts to some dialogs that I use from time to time and that are otherwise difficult to access.
One example would be the "Merge or delete network locations" dialog (screenshot).
Using Process Explorer I found out the following information about that dialog:
C:\Windows\System32\netprof.dll
C:\Windows\system32\DllHost.exe /Processid:{44C39C96-0167-478F-B68D-783294A2545D}
Unfortunately I can't figure out what to do with it.
For other dialogs/locations there are ways like this:
Trash:
%windir%\explorer.exe /n,::{645FF040-5081-101B-9F08-00AA002F954E}
Keyboard:
%systemroot%\system32\control.exe /name Microsoft.RegionalAndLanguageOptions /page /p:"keyboard"
But I can't figure out a general way to do this.
The programming language doesn't matter in this case. You're welcome to post a solution in any language or by the command prompt. Please use the mentioned dialog as an example, but I hope to find out a general solution. Thanks.
Not every dialog can be programmatically accessed as you suggest. Some dialogs are custom to the application that launches them, so you won't be able to easily access them.
I wasn't able to find a reference to the "Merge or delete network locations" dialog that you were primarily interested in.
For the ones that can be accessed, there are basically two types.
Dialogs that can be invoked from the regular Windows command line. As mentioned by kenny in the comments, this serverfault question captures a lot of the known commands.
Another approach would be to launch the dialog through powershell. Powershell can access and launch the .NET framework dialogs. This TechNet Scripting Guys article provides an example of launching the open file dialog through powershell.
The article is well worth reading, but this is the snippet that does the magic.
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "All files (*.*)| *.*"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
} #end function Get-FileName
# *** Entry Point to Script ***
Get-FileName -initialDirectory "c:\fso"
And just in case you wanted something besides the open file dialog, you would change the following line to the dialog you need. $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog

Invoke 'Open' Dialog from Windows Desktop

Is there some way I can programmatically (in VBS) OR by using CMD/RUN open the 'Open' dialog that contains the places bar and a browser but without opening say notepad or MSpaint?
http://i.technet.microsoft.com/dynimg/IC354177.jpg
I'd like to use this on the desktop itself, it would be really cool if there was a DLL I can just use instead of having a VBS file but if not i'm sure its possible in VBS.
I'm busy searching where the actual open dialog box comes from, it should come from some DLL file somewhere.
I might even consider stopping the windows shell from opening all together and just using this open window as the shell on some computers.
Regards, Rocklore
What version of Windows are you on?
"UserAccounts.CommonDialog" was the way to do this in XP. But it no longer exists in Windows 7. You may be able to use some of the flags available for the BrowseForFolder() method to make it look like a file open dialog. See this page for an example.
XP Edit:
Here's an XP example using UserAccounts.CommonDialog.
With CreateObject("UserAccounts.CommonDialog")
.InitialDir = CreateObject("WScript.Shell").SpecialFolders("Desktop")
.Filter = "All Files|*.*"
' Show the dialog. If [Open] is clicked, save the name of the selected file...
If .ShowOpen Then strFile = .FileName
End With

Naming network drives from commandline rather than Windows Explorer

I'm writing a batch file to map multiple servers to drives on my PC. Using the NET USE command, I have managed to map the drives successfully.
When viewed in Windows Explorer, each drive shows the letter assignment and the server name. I'd like to display a user-friendly plain-English name for each server in the Explorer view also (this is different from the volume label). I can right-click on each drive individually in Explorer and rename but this is a bit long-winded.
Is there any way that names can be assigned to the drives from the command prompt (and therefore from a batch file) rather than right-clicking and renaming in Explorer?
You can do it in Powershell like this:
$rename = new-object -ComObject Shell.Application
$rename.NameSpace("X:\").Self.Name = "DriveLabel"
Just replace the X with the drive-letter on which you want to set the label.
Alternatively if you donĀ“t want to use Powershell you can do the following:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\##computername#sharename" /f /v "_LabelFromReg" /t REG_SZ /d "DriveLabel"
Of course you have to replace computername with the servername, the sharename with the name of the share and the Drivelabel with your label
The "label" value for a mapped network drive is stored in the registry.
Look into HKEY_USERS\*SID*\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2. There should be a key that represents the mapped network drive. If there is a value called _LabelFromReg you have a custom label and if the value is not there then it uses the default label, such as, Windows (\server\share) (Z:).
You should also be able to use Group Policy Preference, and Network Folders and Shortcuts to get the labels you want.

PowerShell, Object = Start Process?

Hi I would like to start the Internet Explorer without extensions and control it. (Navigate to other pages, click buttons etc.)
When I use the command: "Start iexplore.exe -ArgumentList -extoff" I have the IExplore without extensions, but no object. I need the object to navigate to different pages and click buttons.
"$ie = Start iexplore.exe -ArgumentList -extoff" is not possible with the Command "Start X"
The following code create a Com Object and all I want is possible without the "Extensions = off"
$ie = New-Object -ComObject InternetExplorer.Application
$ie.Navigate("http://www.stackoverflow.com")
$ie.Navigate("www.Navigate to a other Page.com")
$ie.Document.getElementById("ButtonID")|foreach{
$_.Click()
}
This is a real hack but you could tweak the COM startup commandline for IE to pass in the argument -extoff. The registry entry to start IE on my machine (with IE9) is:
HKEY_CLASSES_ROOT\CLSID{0002DF01-0000-0000-C000-000000000046}\LocalServer32
Note that you might need to override the regkey permissions to edit the value.

Resources