Icon Extraction in VIsta - c#

for extracting special folder icons I'm using
ExtractIconEx(Environment.SystemDirectory + "\\shell32.dll",ncIconIndex, handlesIconLarge, handlesIconSmall, 1);
Here im passing explicitly nIconIndex for special folders like MyDocs,MyPictures ..etc
and its working fine in XP ,however in Vista its not retrieving the correct icons ..there it retrieves yellow folder icons..it should not be the case.
Cn anybody help me on this..

Vista added a new API called SHGetStockIconInfo but it does not support my documents AFAIK. But that does not matter since the method you SHOULD be using works on both XP and Vista (Your current solution will not work when the user has selected a custom icon, you are just looking in hardcoded system dlls, this could change at any point)
So, what you should do is, get the path or PIDL to the shell folder you are interested in (SHGetFolderPath and friends) and pass that path/PIDL to SHGetFileInfo. SHGetFileInfo can give you a icon handle, or the index into the system image list.
I'm not sure what the .NET equivalent for those functions are, but you should be able to figure that out, or use PInvoke

Check out the IconLib library at codeproject.

The best example I've seen of success in this area from .NET (and it was done with VB.NET) is in this article.
http://www.codeproject.com/KB/cpp/VbNetExpTree.aspx
My $.02 is that working with the shell API is extremely painful from .NET due to the level of COM interop required and the complexity of the API's.

Related

How to retrieve an icon/image from the window of a running UWP application?

I am able to get icons from non-UWP apps with the following code:
from win32con GCL_HICON, WM_GETICON,
from win32gui import GetClassLong, SendMessageTimeout
_, icon_handle = SendMessageTimeout(hwnd, WM_GETICON, 1, 0, 0, 50)
if icon_handle == 0:
icon_handle = GetClassLong(hwnd, GCL_HICON)
if icon_handle == 0:
return Settings.BLANK_ICON
Documentation says that the next step should be using LoadIcon/LoadImage to extract it from the executable, but I've tried to avoid that.
SO post says UWP app icon path could be retrieved by SHLoadIndirectString (ctypes.windll.shlwapi.SHLoadIndirectString from Python), but that topic deals with the files associations found in the registry - an open window isn't the starting point.
How can I retrieve that "indirect string" having just a window handle? Or maybe someone knows about some other solution to this problem, I'm interested in any type of icon/image I can get.
EDIT: accepted answer together with this answer reveals a way to solve this with Python and ctypes.
There is not just one icon for a UWP app, there may be many, to be able to adapt to a specific device, form factors, etc.
As #Simon Mourier said, Most of "modern app" (or Windows Store apps, or apps in the AppX application model) information can be queried from official APIs.(I'm just a porter)
You can start with the GetPackageFullName function (it gets the package full name for the specified process). Once you get a package full name, you can use the Package Query API to get more information.
These API are native one, so they don't have equivalent in the .NET Framework to my knowledge. However, they are accessible from WinRT application somehow (and you can indeed access some of the WinRT APIs from standard .NET Framework apps, but this is kindof hack).
The images contained in these apps are special, because they are defined as resources (assets) keys that can be tweaked using qualifiers to form a final path. This is documented for example here: How to name resources using qualifiers (HTML) and here: Quickstart: Using file or image resources (HTML).
The problem is what you can find depends heavily on the application itself, so it's not super easy to determine what image you can use and I have not found any API for this, so I have coded a sample that gets the highest scale image for a given resource name as an exemple (FindHighestScaleQualifiedImagePath). You can load a WPF BitmapSource (or any other imaging platform resource) from this path.
Samples is included in the link provided. For details, please refer to:
Get Icon from UWP App

Win32 Interop using PowerAPI - PowerIsSettingRangeDefined() is an undefined/missing function

I'm currently using C# and Win32 interop to register power setting notifications, enumerate power setting guids, etc. In the process of this, I came across a function in the MSDN documentation called "PowerIsSettingRangeDefined" that looked useful. When I imported the function and tried to test it, the compiler threw "System.EntryPointNotFound" exception. Obviously I double checked my spelling, etc, to no avail. So I looked for the header file on my computer and I did find the function listed in the 'powrprof.h' header for the 8.0 SDK, however, I don't have a copy of the 7.0 or 7.0A SDK on this computer. But according to the documentation, this was supposed to have been implemented starting with Windows 7. So this should have worked...
Then I used ProcessHacker to inspect the export table of the 'powrprof.dll' module in my process. The function was NOT there! To take it one step further, I used PE Explorer on the actual 'powrprof.dll' file located in "C:\Windows\SysWOW64\" and the entry point in question, again, was NOT in the name list. So the official header files include this function with "#if (NTDDI_VERSION >= NTDDI_WIN7)" above, and the documentation shows the function exists starting with Win7, however, it seems the MS team did not include it when compiling 'powrprof.dll' for Windows 7.
Maybe someone can check their copy in Windows 8.1/10 to see if this issue is only on Windows 7? I don't have another version of Windows in this building or I'd test it myself. And I wanted to bring it to attention here first, before trying to report this to Microsoft, just in case I'm missing something.

visual c# button opens file without specifying drive

I work for an IT company where we all carry around flash drives that have our most used programs on them.In my spare time I am hoping to create a "main menu" item that is kind of a fun and convenient way to access these files. I am working on creating this using Visual Studio 2013 and using visual C# windows forms. I have come across a snag however that I can't seem to find a workaround for. I am by no means fluent in C#, but I need to have a button on the windows form open a file without specifying what drive it comes from. I understand that I have to specify a path, but as these will be stored on the flash drives of myself and my coworkers I cannot foresee that the path will always begin with E:. Depending on what USB slot the drive is plugged into it could be N: or F: or the like. I have provided an example below:
Using what I currently know I am opening files using this line of code:
System.Diagnostics.Process.Start("C:/Users/Myname/Desktop/Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
Is there any way possible I can have the file open simply from
System.Diagnostics.Process.Start("Asmodeus/Anti-Virus/Anti-Virus Installers/avast_free_antivirus_setup.exe");
or something of that nature?
Thanks in advance.
There must have been some mis-communication when I asked my question previously. what I am looking to do is open an executable file via a button click on the windows form using a relative path. I am not able to specify the absolute path because the application will be run from a flash drive and therefore will change depending on what USB slot it is currently inserted into.
What I am hoping to accomplish is insert a line of code that will allow me to open an executable file that is located in the \bin\debug folder along with the application itself. I have a picture for clarification but apparently do not have enough reputation to post it. Thank you and sorry for the earlier confusion.
Usually you can just use Environment.GetFolderPath (MSDN) to give you what you need. It doesn't do absolutely everything, but if you need Desktop and the like, that is plenty.
Depending on the target version of .Net, the SpecialFolders exposed are not all there. It may turn out that you need more than they provide, but in your case it doesn't sound like it.
If there is more you need that is not covered in the default, check out this project. I'm sure there are others like it, but it does a little more than the default BCL version, using the API directly. It is at least something to read and learn (and translate from vb.. use an online translator, very quick). I haven't looked at it, but it seems like you are learning this c#/.net thingy, so it might be helpful
This article is about accessing Windows special folders.
These folders include your “Favorites”, “Cookies”, system libraries and the like.
Here is code, including a large number of constant definitions, plus documentation,
allowing access to and creation of these folders.

How do I find which Dlls contain specific W32 functions?

My app is a WPF application and it already has code for the older type of System DPI awareness that works well in every version of windows except 8.1. It turns out that Microsoft added a number of functions to Windows 8.1 as part of their implementation of per-monitor DPI awareness. I need to implement code in my program to support this type of DPI awareness.
I have documentation that lists the per-monitor DPI awareness functions and what their parameters are. I need to import those into C# and call them from my window class. But I don't know which DLLs contain those functions! The documentation for the GetProcessDpiAwareness function, for example, does not indicate which DLL it's in.
How do I find what the exports in the DLLs are?
Right out of head, a dumb method: a binary search in C:\Windows\System32 for GetProcessDpiAwareness, then studying each occurrence with Dependency Walker for exports.
This produces the result: GetProcessDpiAwareness is exported by SHCore.dll.
One may also search the Windows SDK headers and libs, but in my case I haven't found GetProcessDpiAwareness, to my surprise.
Another idea, run the following from the command line prompt:
for %f in (%windir%\system32\*.dll) do dumpbin.exe /exports %f >>%temp%\__exports
Then search %temp%\__exports for the API.
I know it's been asked a while back. (Every time I Google it, this question comes up. So let me share my method.)
If anyone wants to search for functions in DLLs, there's this tool that will do it for you. In case of the GetProcessDpiAwareness on my Windows 10 (64-bit) it is exported from shcore.dll like someone had already mentioned above. Here's the screenshot:
Although I need to preface it by saying that it would be always prudent to refer to the function's documentation on MSDN instead. Currently you can find it at the bottom of each page:
If you play around with the search that I showed above, you will notice that many of the system functions are exported from multiple DLLs (some of which are undocumented.) So if you just blindly go with whatever you find in a search app, you may run a risk of breaking your program in the future if Microsoft changes one of those undocumented functions. So use it only for your own research or curiosity.
Usually functions that work with the same resources are in the same dll's. Look at another dpi function like GetDpiForMonitor and you will see it is in Shcore.dll
Edit: After you find the dll this way you can double check using dependency walker to see what functions are exported from that dll.

WinRT: App to enumerate files outside libraries and known folders

I am working on a Metro app that shows the content of a given folder in a ListView control.
MS decided that developers don't need the System.IO.Directory class and removed it entirely from the framework.
I am looking for a replacement to enumerate files in C# in a metro style app. I have checked all the enumeration samples provided by MS and they all seem to only enumerate the Windows Libraries using the KnownFolders class, something like:
StorageFolder picturesFolder = KnownFolders.PicturesLibrary;
and calling the GetFilesAsync() or GetFoldersAsync() methods depending on your needs. These are all gold if I wanted to enumerate only inside the pictures or music library. However I am looking to enumerate files on directories that are not included in a library.
Anyone knows how this is possible in WinRT???
You are, by design, extremely limited in this area for Metro apps. The idea is that a Metro app is only given access to those things that it is trusted to access, so you can either:
access local storage, specific to your application
access a handful of well-known storage locations, or
access a specifically granted location.
Take a look at http://msdn.microsoft.com/en-us/library/windows/apps/hh464959.aspx to get an idea as to what you'll be able to access.
From http://tirania.org/blog/archive/2011/Sep-15.html :
When you use C# and VB, you are using the full .NET framework. But
they have chosen to expose a smaller subset of the API to developers
to push the new vision for Windows 8.
And this new vision includes safety/sandboxed systems and asynchronous
programming. This is why you do not get direct file system access or
socket access and why synchronous APIs that you were used to consuming
are not exposed.
Now, you notice that I said "exposed" and not "gone".
What they did was that they only exposed to the compiler a set of APIs
when you target the Metro profile. So your application will not
accidentally call File.Create for example. At runtime though, the CLR
will load the full class library, the very one that contains
File.Create, so internally, the CLR could call something like
File.Create, it is just you that will have no access to it.
This split is similar to what has been done in the past with
Silverlight, where not every API was exposed, and where mscorlib was
given rights that your application did not have to ensure the system
safety.
You might be thinking that you can use some trick (referencing the GAC
library instead of the compiler reference or using reflection to get
to private APIs, or P/Invoking into Win32). But all of those uses will
be caught by AppStore review application and you wont be able to
publish your app through Microsoft's store.
You can still do whatever ugly hack you please on your system. It just
wont be possible to publish that through the AppStore.
So there's probably no official way, and if there's an unofficial way, it probably won't be accepted to the app store.
Just in general this makes sense: I don't want to download a seemingly legit application just to have it scan my hard drive and find my "budget.xls" spreadsheet which includes my banking/credit information.
EDIT: it is possible to grant temporary access to secure files/folders through WinRT's file picker, but it has to be invoked and chosen explicitly by the user.
You can use the StorageFolder.GetFolderFromPathAsync Method to get a StorageFolder instance from a path.
StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(#"C:\...");
Note that you may not have permission to do this for all paths on your machine though.
Similar situation. Wanted to access chrome bookmarks file to parse. Had to use FileOpenPicker initially, but the file that it returns can be "cached" in the futureaccesslist(?) for subsequent retrieval.

Categories