Slideshow Wallpaper Windows 7 - c#

How to set Windows 7 Wallpaper slideshow programmatically?
Setting a normal wallpaper
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, String pvParam, UInt32 fWinIni);
private static UInt32 SPI_SETDESKWALLPAPER = 20;
private static UInt32 SPIF_UPDATEINIFILE = 0x1;
public void SetImage(string filename)
{
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, filename, SPIF_UPDATEINIFILE);
}
What i found until now:
There is an ini-file for the slideshow in
C:\Users\CurrentUser\AppData\Roaming\Microsoft\Windows\Themes\
The wallpaper has to be in the following folder during the slideshow:
C:\Users\CurrentUser\AppData\Roaming\Microsoft\Windows\Themes\TranscodedWallpaper.jpg
(during a slideshow the file is changing automatically)

try this
public sealed class Wallpaper
{
Wallpaper() { }
const int SPI_SETDESKWALLPAPER = 20;
const int SPIF_UPDATEINIFILE = 0x01;
const int SPIF_SENDWININICHANGE = 0x02;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni);
public enum Style : int
{
Tiled,
Centered,
Stretched
}
public static void Set(Uri uri, Style style)
{
System.IO.Stream s = new System.Net.WebClient().OpenRead(uri.ToString());
System.Drawing.Image img = System.Drawing.Image.FromStream(s);
string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Control Panel\Desktop", true);
if (style == Style.Stretched)
{
key.SetValue(#"WallpaperStyle", 2.ToString());
key.SetValue(#"TileWallpaper", 0.ToString());
}
if (style == Style.Centered)
{
key.SetValue(#"WallpaperStyle", 1.ToString());
key.SetValue(#"TileWallpaper", 0.ToString());
}
if (style == Style.Tiled)
{
key.SetValue(#"WallpaperStyle", 1.ToString());
key.SetValue(#"TileWallpaper", 1.ToString());
}
SystemParametersInfo(SPI_SETDESKWALLPAPER,
0,
tempPath,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
}
The original question is this

Related

Windows form application to change wallpaper. But it changes to black

public partial class Form1 : Form
{
public string[] allFiles = new string[10];
[DllImport("user32.dll", CharSet =CharSet.Auto)]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, string pvParam, uint fWinIni);
const uint SPI_SETDESKWALLPAPER = 0x14;
const uint SPIF_UPDATEINIFILE = 0x01;
const uint SPIF_SENDWININICHANGE = 0x02;
public Form1()
{
InitializeComponent();
SystemEvents.PowerModeChanged += OnPowerChange;
}
private void OnPowerChange(object sender, PowerModeChangedEventArgs e)
{
switch (e.Mode) {
case PowerModes.Resume:
var result = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, #"F:\abc", SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
Console.WriteLine(result);
string wp = GetWPPath();
Console.WriteLine(wp);
break;
case PowerModes.Suspend:
var res = SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, #"F:\abc", SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
break;
}
}
private static string GetWPPath()
{
RegistryKey wallpaper = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", false);
string wp_path = wallpaper.GetValue("WallPaper").ToString();
wallpaper.Close();
return wp_path;
}
I want to change the wallpaper when i resume laptop from sleep or hibernate. I also checked the registry key, it shows the wallpaper as the path I've set but the desktop background is just black. Is there some kind of reg keys that I have to change or something?
Edit: I hardcoded the file as #"F:\abc", that's the problem. Changed it by mentioning the extension too like #"F:\abc.jpg" and it works. Anyways, I'm gonna change it to an input so shouldn't be a problem. Thanks to all of you.
I have tried to do it in console. It works for me. And later you can add your app to windows autoload.
You must add using System.Runtime.InteropServices;
class Program
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SystemParametersInfo(int uAction,
int uParam, string lpvParam, int fuWinIni);
private static readonly int MAX_PATH = 260;
private static readonly int SPI_GETDESKWALLPAPER = 0x73;
private static readonly int SPI_SETDESKWALLPAPER = 0x14;
private static readonly int SPIF_UPDATEINIFILE = 0x01;
private static readonly int SPIF_SENDWININICHANGE = 0x02;
static string GetDesktopWallpaper()
{
string wallpaper = new string('\0', MAX_PATH);
SystemParametersInfo(SPI_GETDESKWALLPAPER, (int)wallpaper.Length, wallpaper, 0);
return wallpaper.Substring(0, wallpaper.IndexOf('\0'));
}
static void SetDesktopWallpaper(string filename)
{
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, filename,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
static void Main()
{
Console.WriteLine("Enter name:");
//should be like - C:\img.jpg
SetDesktopWallpaper(Console.ReadLine());
}
}

change wallpaper style using c#

i am developing a basic winform application for which i want to change wallpaper using c#, the problem the image is not stretched to fit the screen size.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace DailyWallpaper
{
class WallpaperChanger
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern Int32 SystemParametersInfo(
UInt32 action, UInt32 uParam, String vParam, UInt32 winIni);
private static readonly UInt32 SPI_SETDESKWALLPAPER = 0x14;
private static readonly UInt32 SPIF_UPDATEINIFILE = 0x01;
private static readonly UInt32 SPIF_SENDWININICHANGE = 0x02;
public void SetWallpaper(String path)
{
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
}
}
can anyone tell me how can i rectify this error, thank in advance.
Try executing the following code:
public void SetWallpaper(String path)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Control Panel\Desktop", true);
key.SetValue(#"WallpaperStyle", 2.ToString());
key.SetValue(#"TileWallpaper", 0.ToString());
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}
EDIT:
You can also modify your function and pass a Style to it:
public void SetWallpaper(String path, Style style)
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Control Panel\Desktop", true);
if (style == Style.Stretched)
{
key.SetValue(#"WallpaperStyle", 2.ToString());
key.SetValue(#"TileWallpaper", 0.ToString());
}
if (style == Style.Centered)
{
key.SetValue(#"WallpaperStyle", 1.ToString());
key.SetValue(#"TileWallpaper", 0.ToString());
}
if (style == Style.Tiled)
{
key.SetValue(#"WallpaperStyle", 1.ToString());
key.SetValue(#"TileWallpaper", 1.ToString());
}
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
}

How to set advanced printer settings [duplicate]

We have a project of managing printing documents. At first I wonder why printing options couldn't be set up in single place. For example printer tray selection for first page and for other pages can be done using MS Word automation:
var doc = _applicationObject.Documents.OpenNoRepairDialog(FileName: ref sourceFile, ReadOnly: ref readOnly,
AddToRecentFiles: ref addToRecentFiles,
Visible: ref visible);
doc.PageSetup.FirstPageTray = (WdPaperTray) firstPageTrayCode;
doc.PageSetup.OtherPagesTray = (WdPaperTray) otherPagesTrayCode;
_applicationObject.ActivePrinter = printerPath;
doc.Activate();
_applicationObject.PrintOut(Background: ref backgroundPrint, FileName: sourceFile);
doc.Close(ref saveChanges, ref _missing, ref _missing);
In the code above printer tray is specified as integer because some printers have not standart values for trays (we had this issue with HP - it's tray codes described here). So we first retrieve what trays printer have, using code:
var setting = new PrinterSettings();
setting.PrinterName = myPrinterName;
foreach (PaperSource tray in setting.PaperSources)
{
Console.WriteLine("\t{0}: #{1}", tray.SourceName, tray.RawKind);
}
And this code works with no problems.
But there is no way to specify duplex and staple options here. Duplex can be done, using driver functions OpenPrinter and SetPrinter, like described here and recommended by Microsoft as well in this forum thread.
Staple is completely unclear and if somebody knows by the way how to implement this, please let me know. Using Stapling enum, like in this MSDN article is useless as it requires custom rendering of the document to print.
I described the situation and how parts were implemented. That works fine on our environment: Windows Server 2008 R2, MS Office 2010 x32, Printers HP LaserJet P2055 and Ricoh Nashuatec DSm635. Tested with native and universal PCL6/PCL5e drivers: duplex and tray selection works as expected.
But after deployment the application to client, printers (HP LaserJet 4250 and Ricoh Aficio MP C7501) do printing always from default tray and without duplex. Tried few different drivers with exactly the same result.
In both environments printers are network printers. So to make them apply duplex setting, using printer driver, we needed to install local driver on server and make a local printer, as recommended my Microsoft on this support forum thread.
Though environments and printers used looks very similar, one works while other do not. Any help will be highly appreciated.
In case someone else needs it, I came up with a workaround, based on storing printer settings memory block in a binary file and then restoring it. The idea was described in this blog post, but it didn't work for me when simply copy-pasted (it worked only for some drivers and for some settings while other printing options were ignored).
So I remade it a bit so that now it can support all settings I've tried on any printer (with compatible driver) I've tested. Of course if you use driver of another printer for example it won't work.
The disadvantage of thi approach is of course that you should first set default printer preferences (in Control Panel) to what you need. That isn't always possible of course, but at least in some cases it can help.
So the full source code of a test util which is capable to store printer settings into a file, load this file again into printer and print a document using the specified settings file:
using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Office.Interop.Word;
namespace PrintAdvancedTest
{
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_DEFAULTS
{
public int pDatatype;
public int pDevMode;
public int DesiredAccess;
}
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_INFO_2
{
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pServerName;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pPrinterName;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pShareName;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pPortName;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pDriverName;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pComment;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pLocation;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pSepFile;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pPrintProcessor;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pDatatype;
[MarshalAs(UnmanagedType.LPStr)]
public readonly string pParameters;
public IntPtr pSecurityDescriptor;
public readonly Int32 Attributes;
public readonly Int32 Priority;
public readonly Int32 DefaultPriority;
public readonly Int32 StartTime;
public readonly Int32 UntilTime;
public readonly Int32 Status;
public readonly Int32 cJobs;
public readonly Int32 AveragePPM;
}
public class PrintSettings
{
private const short CCDEVICENAME = 32;
private const short CCFORMNAME = 32;
//Constants for DEVMODE
// Constants for DocumentProperties
private const int DM_MODIFY = 8;
private const int DM_COPY = 2;
private const int DM_IN_BUFFER = DM_MODIFY;
private const int DM_OUT_BUFFER = DM_COPY;
// const intants for dmOrientation
private const int DMORIENT_PORTRAIT = 1;
private const int DMORIENT_LANDSCAPE = 2;
// const intants for dmPrintQuality
private const int DMRES_DRAFT = (-1);
private const int DMRES_HIGH = (-4);
private const int DMRES_LOW = (-2);
private const int DMRES_MEDIUM = (-3);
// const intants for dmTTOption
private const int DMTT_BITMAP = 1;
private const int DMTT_DOWNLOAD = 2;
private const int DMTT_DOWNLOAD_OUTLINE = 4;
private const int DMTT_SUBDEV = 3;
// const intants for dmColor
private const int DMCOLOR_COLOR = 2;
private const int DMCOLOR_MONOCHROME = 1;
// const intants for dmCollate
private const int DMCOLLATE_FALSE = 0;
private const int DMCOLLATE_TRUE = 1;
// const intants for dmDuplex
private const int DMDUP_HORIZONTAL = 3;
private const int DMDUP_SIMPLEX = 1;
private const int DMDUP_VERTICAL = 2;
//const for security access
private const int PRINTER_ACCESS_ADMINISTER = 0x4;
private const int PRINTER_ACCESS_USE = 0x8;
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int PRINTER_ALL_ACCESS =
(STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER
| PRINTER_ACCESS_USE);
/* field selection bits */
private const int DM_ORIENTATION = 0x00000001;
private const int DM_PAPERSIZE = 0x00000002;
private const int DM_PAPERLENGTH = 0x00000004;
private const int DM_PAPERWIDTH = 0x00000008;
private const int DM_SCALE = 0x00000010;
private const int DM_POSITION = 0x00000020;
private const int DM_NUP = 0x00000040;
private const int DM_DISPLAYORIENTATION = 0x00000080;
private const int DM_COPIES = 0x00000100;
private const int DM_DEFAULTSOURCE = 0x00000200;
private const int DM_PRINTQUALITY = 0x00000400;
private const int DM_COLOR = 0x00000800;
private const int DM_DUPLEX = 0x00001000;
private const int DM_YRESOLUTION = 0x00002000;
private const int DM_TTOPTION = 0x00004000;
private const int DM_COLLATE = 0x00008000;
private const int DM_FORMNAME = 0x00010000;
private const int DM_LOGPIXELS = 0x00020000;
private const int DM_BITSPERPEL = 0x00040000;
private const int DM_PELSWIDTH = 0x00080000;
private const int DM_PELSHEIGHT = 0x00100000;
private const int DM_DISPLAYFLAGS = 0x00200000;
private const int DM_DISPLAYFREQUENCY = 0x00400000;
private const int DM_ICMMETHOD = 0x00800000;
private const int DM_ICMINTENT = 0x01000000;
private const int DM_MEDIATYPE = 0x02000000;
private const int DM_DITHERTYPE = 0x04000000;
private const int DM_PANNINGWIDTH = 0x08000000;
private const int DM_PANNINGHEIGHT = 0x10000000;
private const int DM_DISPLAYFIXEDOUTPUT = 0x20000000;
[StructLayout(LayoutKind.Sequential)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCDEVICENAME)]
public string dmDeviceName;
public short dmSpecVersion;
public short dmDriverVersion;
public short dmSize;
public short dmDriverExtra;
public int dmFields;
public short dmOrientation;
public short dmPaperSize;
public short dmPaperLength;
public short dmPaperWidth;
public short dmScale;
public short dmCopies;
public short dmDefaultSource;
public short dmPrintQuality;
public short dmColor;
public short dmDuplex;
public short dmYResolution;
public short dmTTOption;
public short dmCollate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCFORMNAME)]
public string dmFormName;
public short dmUnusedPadding;
public short dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
}
static void Main(string[] args)
{
Dictionary<string, Action> commands = new Dictionary<string, Action>
{
{"save", PrinterPreferencesSave},
{"print", PrinterPreferencesPrint},
{"set", PrinterPreferencesSet},
{"info", PrinterInfo}
};
while (true)
{
Console.Write("Command ({0}): ", string.Join(", ", commands.Keys));
string command = Console.ReadLine();
Action action;
if (!commands.TryGetValue(command, out action))
{
Console.WriteLine("Invalid command");
}
else
{
action();
}
}
}
static void PrinterPreferencesSave()
{
Console.Write("Printer name: ");
string printerName = Console.ReadLine();
Console.Write("Settings file path format: ");
string SettingsFileNameFormat = Console.ReadLine();
string testName;
while (true)
{
Console.Write("SAVE: Settings set name: ");
testName = Console.ReadLine();
if (testName == "end")
{
break;
}
getDevMode(printerName, string.Format(SettingsFileNameFormat, testName));
}
}
static void PrinterPreferencesPrint()
{
Console.Write("Printer name: ");
string printerName = Console.ReadLine();
Console.Write("Settings file path format: ");
string SettingsFileNameFormat = Console.ReadLine();
Console.Write("Document to print: ");
string docToPrintPath = Console.ReadLine();
string testName;
while (true)
{
Console.Write("PRINT: Settings set name: ");
testName = Console.ReadLine();
if (testName == "end")
{
break;
}
string filePath = string.Format(SettingsFileNameFormat, testName);
if (!File.Exists(filePath))
{
Console.WriteLine("File {0} not exists", filePath);
return;
}
var success = setDevMode(printerName, filePath);
if (success)
{
PrintWordDocument(docToPrintPath, printerName);
}
}
}
static void PrinterPreferencesSet()
{
Console.Write("Printer name: ");
string printerName = Console.ReadLine();
Console.Write("Settings file path format: ");
string SettingsFileNameFormat = Console.ReadLine();
string testName;
while (true)
{
Console.Write("SET: Settings set name: ");
testName = Console.ReadLine();
if (testName == "end")
{
break;
}
string filePath = string.Format(SettingsFileNameFormat, testName);
if (!File.Exists(filePath))
{
Console.WriteLine("File {0} not exists", filePath);
return;
}
var success = setDevMode(printerName, filePath);
if(!success)
{
Console.WriteLine("Failed");
}
}
}
private static void PrinterInfo()
{
Console.Write("Printer name: ");
string printerName = Console.ReadLine();
IntPtr hDevMode; // handle to the DEVMODE
IntPtr pDevMode; // pointer to the DEVMODE
DEVMODE devMode; // the actual DEVMODE structure
//var printController = new StandardPrintController();
PrinterSettings printerSettings = new PrinterSettings();
printerSettings.PrinterName = printerName;
// Get a handle to a DEVMODE for the default printer settings
hDevMode = printerSettings.GetHdevmode(printerSettings.DefaultPageSettings);
// Obtain a lock on the handle and get an actual pointer so Windows won't
// move it around while we're futzing with it
pDevMode = GlobalLock(hDevMode);
// Marshal the memory at that pointer into our P/Invoke version of DEVMODE
devMode = (DEVMODE)Marshal.PtrToStructure(pDevMode, typeof(DEVMODE));
Dictionary<string, int> dmConstants = new Dictionary<string, int>
{
{"DM_ORIENTATION", 0x00000001},
{"DM_PAPERSIZE", 0x00000002},
{"DM_PAPERLENGTH", 0x00000004},
{"DM_PAPERWIDTH", 0x00000008},
{"DM_SCALE", 0x00000010},
{"DM_POSITION", 0x00000020},
{"DM_NUP", 0x00000040},
{"DM_DISPLAYORIENTATION", 0x00000080},
{"DM_COPIES", 0x00000100},
{"DM_DEFAULTSOURCE", 0x00000200},
{"DM_PRINTQUALITY", 0x00000400},
{"DM_COLOR", 0x00000800},
{"DM_DUPLEX", 0x00001000},
{"DM_YRESOLUTION", 0x00002000},
{"DM_TTOPTION", 0x00004000},
{"DM_COLLATE", 0x00008000},
{"DM_FORMNAME", 0x00010000},
{"DM_LOGPIXELS", 0x00020000},
{"DM_BITSPERPEL", 0x00040000},
{"DM_PELSWIDTH", 0x00080000},
{"DM_PELSHEIGHT", 0x00100000},
{"DM_DISPLAYFLAGS", 0x00200000},
{"DM_DISPLAYFREQUENCY", 0x00400000},
{"DM_ICMMETHOD", 0x00800000},
{"DM_ICMINTENT", 0x01000000},
{"DM_MEDIATYPE", 0x02000000},
{"DM_DITHERTYPE", 0x04000000},
{"DM_PANNINGWIDTH", 0x08000000},
{"DM_PANNINGHEIGHT", 0x10000000},
{"DM_DISPLAYFIXEDOUTPUT", 0x20000000},
};
Console.WriteLine("Allow set: {0}. Details: {1}", Convert.ToString(devMode.dmFields, 16), string.Join(",", dmConstants.Where(c=>(devMode.dmFields & c.Value)==c.Value).Select(c=>c.Key)));
//private const int DM_POSITION = 0x00000020;
//private const int DM_NUP = 0x00000040;
//private const int DM_DISPLAYORIENTATION = 0x00000080;
//private const int DM_DEFAULTSOURCE = 0x00000200;
//private const int DM_PRINTQUALITY = 0x00000400;
//private const int DM_COLOR = 0x00000800;
//private const int DM_YRESOLUTION = 0x00002000;
//private const int DM_TTOPTION = 0x00004000;
//private const int DM_FORMNAME = 0x00010000;
//private const int DM_LOGPIXELS = 0x00020000;
//private const int DM_BITSPERPEL = 0x00040000;
//private const int DM_PELSWIDTH = 0x00080000;
//private const int DM_PELSHEIGHT = 0x00100000;
//private const int DM_DISPLAYFLAGS = 0x00200000;
//private const int DM_DISPLAYFREQUENCY = 0x00400000;
//private const int DM_ICMMETHOD = 0x00800000;
//private const int DM_ICMINTENT = 0x01000000;
//private const int DM_MEDIATYPE = 0x02000000;
//private const int DM_DITHERTYPE = 0x04000000;
//private const int DM_PANNINGWIDTH = 0x08000000;
//private const int DM_PANNINGHEIGHT = 0x10000000;
//private const int DM_DISPLAYFIXEDOUTPUT = 0x20000000;
WriteDevModePropertyInfo("DeviceName", devMode.dmDeviceName, null);
WriteDevModePropertyInfo("SpecVersion", devMode.dmSpecVersion.ToString(), null);
WriteDevModePropertyInfo("DriverVersion", devMode.dmDriverVersion.ToString(), null);
WriteDevModePropertyInfo("Size", devMode.dmSize.ToString(), null);
WriteDevModePropertyInfo("DriverExtra", devMode.dmDriverExtra.ToString(), null);
WriteDevModePropertyInfo("Orientation", devMode.dmOrientation.ToString(), (devMode.dmFields & DM_ORIENTATION) == DM_ORIENTATION);
WriteDevModePropertyInfo("PaperSize", devMode.dmPaperSize.ToString(), (devMode.dmFields & DM_PAPERSIZE) == DM_PAPERSIZE);
WriteDevModePropertyInfo("PaperLength", devMode.dmPaperLength.ToString(), (devMode.dmFields & DM_PAPERLENGTH) == DM_PAPERLENGTH);
WriteDevModePropertyInfo("PaperWidth", devMode.dmPaperWidth.ToString(), (devMode.dmFields & DM_PAPERWIDTH) == DM_PAPERWIDTH);
WriteDevModePropertyInfo("Scale", devMode.dmScale.ToString(), (devMode.dmFields & DM_SCALE) == DM_SCALE);
WriteDevModePropertyInfo("Copies", devMode.dmCopies.ToString(), (devMode.dmFields & DM_COPIES) == DM_COPIES);
WriteDevModePropertyInfo("Duplex", devMode.dmDuplex.ToString(), (devMode.dmFields & DM_DUPLEX) == DM_DUPLEX);
WriteDevModePropertyInfo("YResolution", devMode.dmYResolution.ToString(), null);
WriteDevModePropertyInfo("TTOption", devMode.dmTTOption.ToString(), null);
WriteDevModePropertyInfo("Collate", devMode.dmCollate.ToString(), (devMode.dmFields & DM_COLLATE) == DM_COLLATE);
WriteDevModePropertyInfo("FormName", devMode.dmFormName.ToString(), null);
WriteDevModePropertyInfo("UnusedPadding", devMode.dmUnusedPadding.ToString(), null);
WriteDevModePropertyInfo("BitsPerPel", devMode.dmBitsPerPel.ToString(), null);
WriteDevModePropertyInfo("PelsWidth", devMode.dmPelsWidth.ToString(), null);
WriteDevModePropertyInfo("PelsHeight", devMode.dmPelsHeight.ToString(), null);
WriteDevModePropertyInfo("DisplayFlags", devMode.dmDisplayFlags.ToString(), null);
WriteDevModePropertyInfo("DisplayFrequency", devMode.dmDisplayFlags.ToString(), null);
}
private static void WriteDevModePropertyInfo(string settingName, string value, bool? allowSet)
{
Console.WriteLine("{0} {1} {2}", allowSet.HasValue ? (allowSet.Value ? "+" : "-") : " ", settingName.PadRight(20, '.'), value);
}
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GlobalFree(IntPtr handle);
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GlobalLock(IntPtr handle);
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GlobalUnlock(IntPtr handle);
[DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern Int32 GetLastError();
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,
[MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg,
IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);
[DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true,
CharSet = CharSet.Ansi, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall)]
private static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel,
IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded);
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA",
SetLastError = true, CharSet = CharSet.Ansi,
ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
private static extern bool
OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
out IntPtr hPrinter, ref PRINTER_DEFAULTS pd);
[DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr
pPrinter, int Command);
[DllImport("kernel32.dll")]
static extern IntPtr GlobalAlloc(uint uFlags, int dwBytes);
public static void getDevMode(string printerName, string filepath)
{
PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();
PrinterValues.pDatatype = 0;
PrinterValues.pDevMode = 0;
PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
IntPtr ptrZero = IntPtr.Zero;
IntPtr hPrinter;
IntPtr pDevMode = new IntPtr();
//get printer handle
OpenPrinter(printerName, out hPrinter, ref PrinterValues);
//allocate memory for ptr to devmode, 0 argument retrieves bytes required
int bytes = DocumentProperties(new IntPtr(0), hPrinter, printerName, ptrZero, ref pDevMode, 0);
pDevMode = GlobalAlloc(0, bytes);
//set the pointer
DocumentProperties(new IntPtr(0), hPrinter, printerName, pDevMode, ref ptrZero, DM_OUT_BUFFER);
//write the devMode to a file
using (FileStream fs = new FileStream(filepath, FileMode.Create))
{
for (int i = 0; i < bytes; i++)
{
fs.WriteByte(Marshal.ReadByte(pDevMode, i));
}
}
//free resources
GlobalFree(pDevMode);
ClosePrinter(hPrinter);
}
public static bool setDevMode(string printerName, string filepath)
{
if(!File.Exists(filepath))
{
return false;
}
IntPtr hPrinter;
int bytes = 0;
IntPtr pPInfo;
IntPtr pDevMode;
PRINTER_INFO_2 pInfo = new PRINTER_INFO_2();
PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();
PrinterValues.pDatatype = 0;
PrinterValues.pDevMode = 0;
PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
//retrieve the devmode from file
using (FileStream fs = new FileStream(filepath, FileMode.Open))
{
int length = Convert.ToInt32(fs.Length);
pDevMode = GlobalAlloc(0, length);
for (int i = 0; i < length; i++)
{
Marshal.WriteByte(pDevMode, i, (byte)fs.ReadByte());
}
}
//get printer handle
OpenPrinter(printerName, out hPrinter, ref PrinterValues);
//get bytes for printer info structure and allocate memory
GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out bytes);
if (bytes == 0)
{
throw new Exception("Get Printer Failed");
}
pPInfo = GlobalAlloc(0, bytes);
//set pointer to printer info
GetPrinter(hPrinter, 2, pPInfo, bytes, out bytes);
//place the printer info structure
pInfo = (PRINTER_INFO_2)Marshal.PtrToStructure(pPInfo, typeof(PRINTER_INFO_2));
//insert the new devmode
pInfo.pDevMode = pDevMode;
pInfo.pSecurityDescriptor = IntPtr.Zero;
//set pointer to new printer info
Marshal.StructureToPtr(pInfo, pPInfo, true);
//update
SetPrinter(hPrinter, 2, pPInfo, 0);
//free resources
GlobalFree(pPInfo);
GlobalFree(pDevMode);
ClosePrinter(hPrinter);
return true;
}
private static void PrintWordDocument(string path, string printerName)
{
object readOnly = true;
object addToRecentFiles = false;
object visible = false;
object backgroundPrint = false;
object saveChanges = false;
object sourceFile = path;
var wordApplication = new Application();
var doc = wordApplication.Documents.OpenNoRepairDialog(FileName: ref sourceFile, ReadOnly: ref readOnly,
AddToRecentFiles: ref addToRecentFiles,
Visible: ref visible);
wordApplication.ActivePrinter = printerName;
doc.Activate();
wordApplication.PrintOut(Background: ref backgroundPrint, FileName: sourceFile);
object _missing = Type.Missing;
doc.Close(ref saveChanges, ref _missing, ref _missing);
}
}
}
UPDATE 2018-12-04 (in 5,5 years): There was a nasty rare problem with Marshal.StructureToPtr call in this code and today I finally got an answer to that question (see comment from Hans Passant). I'm not able to verify if that actually works since I no longer work on that project, but it seems you may need to apply that fix if you try using this code.

using SHFILEINFO to get file icons

I've been searching for a c# library that gets the icon of a given path with many sizes, finally when I got exactly the class that I need, It has a problem:
This method gets icon of a given path:
public static BitmapSource GetIcon(string FileName, bool small, bool checkDisk, bool addOverlay)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
uint SHGFI_LINKOVERLAY = 0x000008000;
uint flags;
if (small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
if (!checkDisk)
flags |= SHGFI_USEFILEATTRIBUTES;
if (addOverlay)
flags |= SHGFI_LINKOVERLAY;
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var ico = System.Drawing.Icon.FromHandle(shinfo.hIcon); //**Here**
var bs = BitmapFromIcon(ico);
ico.Dispose();
bs.Freeze();
DestroyIcon(shinfo.hIcon);
// CloseHandle(shinfo.hIcon); it always give exception
return bs;
}
public static extern Boolean CloseHandle(IntPtr handle);
The previous code as it is in this question works as it suppose to, however AFTER getting the icons of file paths in a directory successfully, it gives an exception on this line :
var ico = System.Drawing.Icon.FromHandle(shinfo.hIcon);
An exception of type 'System.IO.FileNotFoundException' occurred in WPF_REMOTE.exe but was not handled in user code
Additional information: Unable to find the specified file.
So Why is this happening?
Update: I found out that it happened because there were a path that contains unicode characters and i need to use SHFILEINFOW instead, still can't figure how to change SHFILEINFO to SHFILEINFOW
another question about the line CloseHandle(shinfo.hIcon); always give an exception :
An exception of type 'System.Runtime.InteropServices.SEHException' occurred in WPF_REMOTE.exe but was not handled in user code
Additional information: External component has thrown an exception.
I'm wondering why it's not working! and why should I use it if the method is already working without it.
also if you have any improvement I could use in this class tell me, Thanks in Advance.
After editing some code I get it, you can get the icons easily from this library, in my case i needed the icon as byte[]
public class IconHelper
{
// Constants that we need in the function call
private const int SHGFI_ICON = 0x100;
private const int SHGFI_SMALLICON = 0x1;
private const int SHGFI_LARGEICON = 0x0;
private const int SHIL_JUMBO = 0x4;
private const int SHIL_EXTRALARGE = 0x2;
// This structure will contain information about the file
public struct SHFILEINFO
{
// Handle to the icon representing the file
public IntPtr hIcon;
// Index of the icon within the image list
public int iIcon;
// Various attributes of the file
public uint dwAttributes;
// Path to the file
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string szDisplayName;
// File type
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public static extern Boolean CloseHandle(IntPtr handle);
private struct IMAGELISTDRAWPARAMS
{
public int cbSize;
public IntPtr himl;
public int i;
public IntPtr hdcDst;
public int x;
public int y;
public int cx;
public int cy;
public int xBitmap; // x offest from the upperleft of bitmap
public int yBitmap; // y offset from the upperleft of bitmap
public int rgbBk;
public int rgbFg;
public int fStyle;
public int dwRop;
public int fState;
public int Frame;
public int crEffect;
}
[StructLayout(LayoutKind.Sequential)]
private struct IMAGEINFO
{
public IntPtr hbmImage;
public IntPtr hbmMask;
public int Unused1;
public int Unused2;
public Rect rcImage;
}
[DllImport("shell32.dll", EntryPoint = "#727")]
private extern static int SHGetImageList(
int iImageList,
ref Guid riid,
out IImageList ppv
);
// The signature of SHGetFileInfo (located in Shell32.dll)
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
[DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
public static extern int SHGetFileInfo(IntPtr pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
[DllImport("shell32.dll", SetLastError = true)]
static extern int SHGetSpecialFolderLocation(IntPtr hwndOwner, Int32 nFolder,
ref IntPtr ppidl);
[DllImport("user32")]
public static extern int DestroyIcon(IntPtr hIcon);
public struct pair
{
public System.Drawing.Icon icon { get; set; }
public IntPtr iconHandleToDestroy { set; get; }
}
private static byte[] ByteFromIcon(System.Drawing.Icon ic)
{
var icon = System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(ic.Handle,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
icon.Freeze();
byte[] data;
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(icon));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
private static byte[] GetSmallIcon(string FileName, IconSize iconSize)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint flags;
if (iconSize == IconSize.Small)
{
flags = SHGFI_ICON | SHGFI_SMALLICON;
}
else
{
flags = SHGFI_ICON | SHGFI_LARGEICON;
}
var res = SHGetFileInfo(FileName, 0, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var ico = (System.Drawing.Icon)System.Drawing.Icon.FromHandle(shinfo.hIcon);
var bs = ByteFromIcon(ico);
ico.Dispose();
DestroyIcon(shinfo.hIcon);
return bs;
}
private static byte[] GetLargeIcon(string FileName)
{
SHFILEINFO shinfo = new SHFILEINFO();
uint SHGFI_SYSICONINDEX = 0x4000;
int FILE_ATTRIBUTE_NORMAL = 0x80;
uint flags;
flags = SHGFI_SYSICONINDEX;
var res = SHGetFileInfo(FileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, Marshal.SizeOf(shinfo), flags);
if (res == 0)
{
throw (new System.IO.FileNotFoundException());
}
var iconIndex = shinfo.iIcon;
Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
IImageList iml;
int size = SHIL_EXTRALARGE;
var hres = SHGetImageList(size, ref iidImageList, out iml); // writes iml
IntPtr hIcon = IntPtr.Zero;
int ILD_TRANSPARENT = 1;
hres = iml.GetIcon(iconIndex, ILD_TRANSPARENT, ref hIcon);
var ico = System.Drawing.Icon.FromHandle(hIcon);
var bs = ByteFromIcon(ico);
ico.Dispose();
DestroyIcon(hIcon);
return bs;
}
}
and you can get four different sizes for the icon

To show the properties page of a file and navigate to a tab

In my software i need to show the property dialog of a file and navigate to a specific tab in that property dialog? please tell me how to acheive this using c#?
or
Is it possible to replace the default property dialog with a custom one?
private bool properties(string Filename)
{
SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
info.lpVerb = "properties";
info.lpParameters = "Details";
info.lpFile = Filename;
info.nShow = SW_SHOW;
info.fMask = SEE_MASK_INVOKEIDLIST;
return ShellExecuteEx(ref info);
}
By setting info.lpParameters to name of the tab you want it gets opened with that tab selected. In my case "Details"...
Yes you need that declaration that codeteq wrote.
This is the declaration that I use:
private const int SW_SHOW = 5;
private const uint SEE_MASK_INVOKEIDLIST = 12;
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHELLEXECUTEINFO
{
public int cbSize;
public uint fMask;
public IntPtr hwnd;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpVerb;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpParameters;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpDirectory;
public int nShow;
public IntPtr hInstApp;
public IntPtr lpIDList;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpClass;
public IntPtr hkeyClass;
public uint dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}
You must use P/Invoke to achieve this:
private const int SW_SHOW = 5;
private const uint SEE_MASK_INVOKEIDLIST = 12;
[DllImport("shell32.dll")]
static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
public static void ShowFileProperties(string filename)
{
SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
info.lpVerb = "properties";
info.lpFile = filename;
info.nShow = SW_SHOW;
info.fMask = SEE_MASK_INVOKEIDLIST;
ShellExecuteEx(ref info);
}
don't know if it's even possible to select a specific tab (in a nice way)...

Categories

Resources