hi everyone i need to make the time zone for my windows CE 6 changed to
"(GMT +03:00) Kuwait, Riyadh"
and this my code
[DllImport("coredll.dll", CharSet = CharSet.Auto)]
private static extern int GetTimeZoneInformation(out TimeZoneInformation lpTimeZoneInformation);
[DllImport("coredll.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation(ref TimeZoneInformation lpTimeZoneInformation);
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public int wYear;
public int wMonth;
public int wDayOfWeek;
public int wDay;
public int wHour;
public int wMinute;
public int wSecond;
public int wMilliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TimeZoneInformation
{
public int bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string standardName;
public SYSTEMTIME standardDate;
public int standardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string daylightName;
public SYSTEMTIME daylightDate;
public int daylightBias;
}
how can I use this code to set the time zone for the specific one
please any one can help me.
I found the solution by adding a registry file with this script.
[HKEY_LOCAL_MACHINE\Time Zones]
"Default"="Arab Standard Time"
Related
Public Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
This is my original VB6 code and the converted C# code is
public struct WIN32_FIND_DATA
{
long dwFileAttributes;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
long nFileSizeHigh;
long nFileSizeLow;
long dwReserved0;
long dwReserved1;
cFileName As String * max_path;
cAlternate As String * 14
}
How to convert cFileName As String * max_path into C#
It seems that you want to marshal this struct (e.g. when calling FindFirstFileEx, FindNextFile API functions); if it's your case
using System.Runtime.InteropServices;
...
[StructLayout(LayoutKind.Sequential)]
struct WIN32_FIND_DATA
{
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)] // MAX_PATH = 260
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
see original WIN32_FIND_DATA declaration for details
Trying to use the following code example which works fine in WinForm application but not in VSTO. Is there some sort of permissions that allow access?
Can set the default printer but can't get or set printer settings.
Get the following exception from within addin:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
http://www.pinvoke.net/default.aspx/winspool.SetDefaultPrinter
http://www.pinvoke.net/default.aspx/winspool/OpenPrinter.html
visual studio project template is a {Word/Outlook} 2013 and 2016 VSTO Add-in
string name = #"\\{printer server name}\{printer name}";
PRNsettings p = new PRNsettings();
var v = p.ChangePrinterSetting(name, new PrinterData { colour = 1, copies = 1, duplex = 1, source = 7 });
public class PrinterData
{
public PrinterData()
{
copies = -1;
colour = -1;
duplex = -1;
source = -1;
}
public int copies { get; set; }
public int colour { get; set; }
public int duplex { get; set; }
public int source { get; set; }
}
public class PRNsettings
{
private IntPtr hPrinter = new System.IntPtr();
private PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();
private PRINTER_INFO_2 pinfo = new PRINTER_INFO_2();
private DEVMODE dm;
private IntPtr ptrDM;
private IntPtr ptrPrinterInfo;
private int sizeOfDevMode = 0;
private int lastError;
private int nBytesNeeded;
private long nRet;
private int intError;
private System.Int32 nJunk;
private IntPtr yDevModeData;
[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", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, PRINTER_DEFAULTS pDefault);
[DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr pPrinter, int Command);
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Name);
[StructLayout(LayoutKind.Sequential)]
public struct PRINTER_DEFAULTS
{
public int pDatatype;
public int pDevMode;
public int DesiredAccess;
}
[StructLayout(LayoutKind.Sequential)]
private struct PRINTER_INFO_2
{
[MarshalAs(UnmanagedType.LPStr)] public string pServerName;
[MarshalAs(UnmanagedType.LPStr)] public string pPrinterName;
[MarshalAs(UnmanagedType.LPStr)] public string pShareName;
[MarshalAs(UnmanagedType.LPStr)] public string pPortName;
[MarshalAs(UnmanagedType.LPStr)] public string pDriverName;
[MarshalAs(UnmanagedType.LPStr)] public string pComment;
[MarshalAs(UnmanagedType.LPStr)] public string pLocation;
public IntPtr pDevMode;
[MarshalAs(UnmanagedType.LPStr)] public string pSepFile;
[MarshalAs(UnmanagedType.LPStr)] public string pPrintProcessor;
[MarshalAs(UnmanagedType.LPStr)] public string pDatatype;
[MarshalAs(UnmanagedType.LPStr)] public string pParameters;
public IntPtr pSecurityDescriptor;
public Int32 Attributes;
public Int32 Priority;
public Int32 DefaultPriority;
public Int32 StartTime;
public Int32 UntilTime;
public Int32 Status;
public Int32 cJobs;
public Int32 AveragePPM;
}
private const short CCDEVICENAME = 32;
private const short CCFORMNAME = 32;
[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;
public uint dmMediaType;
}
private const int DM_DUPLEX = 0x1000;
private const int DM_IN_BUFFER = 8;
private const int DM_OUT_BUFFER = 2;
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);
public int returnSource;
public int returnDuplex;
public int returnColor;
public int returnCopies;
public bool SetDefault(string name)
{
try
{
return SetDefaultPrinter(name);
}
catch (Exception) { return false; }
}
public bool ChangePrinterSetting(string PrinterName, PrinterData PS)
{
try
{
dm = this.GetPrinterSettings(PrinterName);
// Sent back to allow reset of the settings back to original.
returnSource = dm.dmDefaultSource;
returnDuplex = dm.dmDuplex;
returnColor = dm.dmColor;
returnCopies = dm.dmCopies;
if (PS.source > -1)
dm.dmDefaultSource = (short)PS.source;
if (PS.duplex > -1)
dm.dmDuplex = (short)PS.duplex;
if (PS.colour > -1)
dm.dmColor = (short)PS.colour;
if (PS.copies > -1)
dm.dmCopies = (short)PS.copies;
Marshal.StructureToPtr(dm, yDevModeData, true);
pinfo.pDevMode = yDevModeData;
pinfo.pSecurityDescriptor = IntPtr.Zero;
Marshal.StructureToPtr(pinfo, ptrPrinterInfo, false);
lastError = Marshal.GetLastWin32Error();
nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));
// Error
if (nRet == 0)
return false;
if (hPrinter != IntPtr.Zero)
ClosePrinter(hPrinter);
return Convert.ToBoolean(nRet);
}
catch (Exception) { return false; }
}
public DEVMODE GetPrinterSettings(string PrinterName)
{
PrinterData PData = new PrinterData();
DEVMODE dm;
const int PRINTER_ACCESS_ADMINISTER = 0x4;
const int PRINTER_ACCESS_USE = 0x8;
const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
PrinterValues.pDatatype = 0;
PrinterValues.pDevMode = 0;
PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
nRet = Convert.ToInt32(OpenPrinter(PrinterName,
out hPrinter, PrinterValues));
GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out nBytesNeeded);
Marshal.AllocCoTaskMem(nBytesNeeded);
ptrPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded);
nRet = Convert.ToInt32(GetPrinter(hPrinter, 2, ptrPrinterInfo, nBytesNeeded, out nJunk));
pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure(ptrPrinterInfo, typeof(PRINTER_INFO_2));
IntPtr Temp = new IntPtr();
if (pinfo.pDevMode == IntPtr.Zero)
{
IntPtr ptrZero = IntPtr.Zero;
sizeOfDevMode = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrZero, ref ptrZero, 0);
ptrDM = Marshal.AllocCoTaskMem(sizeOfDevMode);
int i = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, ptrDM, ref ptrZero, DM_OUT_BUFFER);
pinfo.pDevMode = ptrDM;
}
intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, IntPtr.Zero, ref Temp, 0);
yDevModeData = Marshal.AllocHGlobal(intError);
intError = DocumentProperties(IntPtr.Zero, hPrinter, PrinterName, yDevModeData, ref Temp, 2);
dm = (DEVMODE)Marshal.PtrToStructure(yDevModeData, typeof(DEVMODE));
return dm;
}
}
If you get this error when building for AnyCPU or x64 you might find my answer here helpfull:
WinSpool OpenPrinter Access Denied - building for AnyCPU\x64
Here is my main program:
class Program
{
static void Main(string[] args)
{
Printer printer = new Printer();
IntPtr printerHandle = printer.getPrinterHandle("TASKalfa 2551ci");
UInt32 jobId = printer.getJobId();
Console.WriteLine(printerHandle+","+jobId);
printer.getJob(printerHandle, jobId);
Console.ReadLine();
}
}
I got the following error message from VS 2015 Community Edition, when I call printer.getJob Method, even I have catched the System.NullReferenceException.
System.NullReferenceException was unhandled
Message: An unhandled exception of type 'System.NullReferenceException' occurred in mscorlib.dll
Additional information: Object reference not set to an instance of an object.
I have checked that both variable printerHandle and jobId are not null, so I cannot figure out what is problem.
However the value of printerHandle is not a constant, is it correct?
Here is my printer object source code:
using System;
using System.Collections;
using System.Management;
using System.Runtime.InteropServices;
class Printer
{
public Printer()
{
}
public ArrayList getPrinterNameList()
{
ArrayList result = new ArrayList();
var printerQuery = new ManagementObjectSearcher("SELECT * from Win32_Printer");
foreach (var printer in printerQuery.Get())
{
result.Add(printer.GetPropertyValue("Name"));
}
return result;
}
public UInt32 getJobId()
{
UInt32 jobId=0;
var printJobQuery = new ManagementObjectSearcher("select * from Win32_PrintJob");
foreach (var printJob in printJobQuery.Get())
{
jobId= (UInt32)printJob.Properties["JobId"].Value;
}
return jobId;
}
public IntPtr getPrinterHandle(String printerName)
{
IntPtr result=new IntPtr(0);
Console.WriteLine ("OpenPrinter="+OpenPrinter(printerName,out result, result));
return result;
}
public void getJob(IntPtr printerHandle,UInt32 jobId)
{
int BUFFER_SIZE = 250;
IntPtr pcbNeeed = new IntPtr(0);
byte[] byteBuffer = new byte[BUFFER_SIZE];
try
{
Console.WriteLine("GetJob="+GetJob(printerHandle, (Int32)jobId, 1, out byteBuffer, BUFFER_SIZE, out pcbNeeed));
}
catch (System.NullReferenceException err)
{
Console.WriteLine(err.Message);
}
}
[DllImport("winspool.drv", SetLastError = true)]
static extern int OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);
[DllImport(
"winspool.drv",
EntryPoint = "GetJobW",
SetLastError = true,
CharSet = CharSet.Ansi,
ExactSpelling = false,
CallingConvention = CallingConvention.StdCall)]
private static extern bool GetJob
([InAttribute()] IntPtr hPrinter,
[InAttribute()] Int32 JobId,
[InAttribute()] Int32 Level,
[OutAttribute()] out byte[] pJob,
[InAttribute()] Int32 cbBuf,
[OutAttribute()] out IntPtr pcbNeeded);
}
Here is my WIN API version:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string msg = null;
var hPrinter = new IntPtr();
bool open = NativeMethods.OpenPrinterW("TASKalfa 2551ci", ref hPrinter, IntPtr.Zero);
Debug.Assert(open);
/* Query for 99 jobs */
const uint firstJob = 0u;
const uint noJobs = 99u;
const uint level = 1u;
// Get byte size required for the function
uint needed;
uint returned;
IntPtr tempptr = IntPtr.Zero;
bool b1 = NativeMethods.EnumJobsW(
hPrinter, firstJob, noJobs, level, IntPtr.Zero, 0, out needed, out returned);
uint lastError = NativeMethods.GetLastError();
Console.WriteLine("b1="+b1);
//Debug.Assert(lastError == NativeConstants.ERROR_INSUFFICIENT_BUFFER);
NativeMethods.FormatMessage(0x1300, ref tempptr, lastError, 0, ref msg, 255, ref tempptr);
Console.WriteLine("lastError=" + msg);
// Populate the structs
IntPtr pJob = Marshal.AllocHGlobal((int)needed);
uint bytesCopied;
uint structsCopied;
bool b2 = NativeMethods.EnumJobsW(
hPrinter, firstJob, noJobs, level, pJob, needed, out bytesCopied, out structsCopied);
lastError = NativeMethods.GetLastError();
Console.WriteLine("b2="+b2);
NativeMethods.FormatMessage(0x1300, ref tempptr, lastError, 0, ref msg, 255, ref tempptr);
Console.WriteLine("lastError="+ msg);
var jobInfos = new JOB_INFO_1W[structsCopied];
int sizeOf = Marshal.SizeOf(typeof(JOB_INFO_1W));
IntPtr pStruct = pJob;
for (int i = 0; i < structsCopied; i++)
{
var jobInfo_1W = (JOB_INFO_1W)Marshal.PtrToStructure(pStruct, typeof(JOB_INFO_1W));
jobInfos[i] = jobInfo_1W;
pStruct += sizeOf;
}
Marshal.FreeHGlobal(pJob);
Console.WriteLine("structsCopied="+structsCopied);
Console.ReadLine();
}
public class NativeConstants
{
public const int ERROR_INSUFFICIENT_BUFFER = 122;
}
public partial class NativeMethods
{
[DllImport("kernel32.dll", EntryPoint = "GetLastError")]
public static extern uint GetLastError();
[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
public extern static int FormatMessage(int flag, ref IntPtr source, uint msgid, int langid, ref string buf, int size, ref IntPtr args);
}
public partial class NativeMethods
{
[DllImport("Winspool.drv", EntryPoint = "OpenPrinterW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenPrinterW([In] [MarshalAs(UnmanagedType.LPWStr)] string pPrinterName,
ref IntPtr phPrinter, [In] IntPtr pDefault);
[DllImport("Winspool.drv", EntryPoint = "EnumJobsW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumJobsW([In] IntPtr hPrinter, uint FirstJob, uint NoJobs, uint Level, IntPtr pJob,
uint cbBuf, [Out] out uint pcbNeeded, [Out] out uint pcReturned);
}
[StructLayout(LayoutKind.Sequential)]
public struct JOB_INFO_1W
{
public uint JobId;
[MarshalAs(UnmanagedType.LPWStr)]
public string pPrinterName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pMachineName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pUserName;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDocument;
[MarshalAs(UnmanagedType.LPWStr)]
public string pDatatype;
[MarshalAs(UnmanagedType.LPWStr)]
public string pStatus;
public uint Status;
public uint Priority;
public uint Position;
public uint TotalPages;
public uint PagesPrinted;
public SYSTEMTIME Submitted;
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
}
}
I am using Windows 10.
This is my solution:
using System;
using System.Text;
using System.Management;
using System.Runtime.InteropServices;
namespace WinApi
{
class PrintJob
{
private const int ERROR_INSUFFICIENT_BUFFER = 122;
public PrintJob()
{
string sql = "select * from Win32_PrintJob";
var printJobQuery = new ManagementObjectSearcher(sql);
foreach (ManagementObject printJob in printJobQuery.Get())
{
getJobDetail(printJob);
Console.WriteLine("====================");
}
}
private void getJobDetail(ManagementObject thePrintJob)
{
UInt32 jobId = 0, needed = 0;
String printerName;
bool result;
IntPtr printerHandle = new IntPtr(0);
jobId = (UInt32)thePrintJob.Properties["JobId"].Value;
printerName = (String)thePrintJob.Properties["DriverName"].Value;
Console.WriteLine("Job Id=" + jobId + ",Printer Name=" + printerName);
result=OpenPrinter(printerName,out printerHandle, IntPtr.Zero);
Console.Write("Open Printer " + printerName);
if (result)
{
Console.WriteLine(" success.");
result = GetJob(printerHandle, jobId, 2, IntPtr.Zero,0,out needed);
if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
Console.WriteLine("Get Job 1 failure, error code=" + Marshal.GetLastWin32Error());
else
{
Console.WriteLine("buffer size required=" + needed);
IntPtr buffer = Marshal.AllocHGlobal((int)needed);
result = GetJob(printerHandle, jobId, 2, buffer, needed, out needed);
JOB_INFO_2 jobInfo=(JOB_INFO_2)Marshal.PtrToStructure(buffer, typeof(JOB_INFO_2));
DEVMODE dMode = (DEVMODE)Marshal.PtrToStructure(jobInfo.pDevMode, typeof(DEVMODE));
Console.WriteLine("Job Id=" + jobInfo.JobId + ",Printer Name=" + Marshal.PtrToStringAnsi(jobInfo.pDriverName) + ",Copies=" + dMode.dmCopies);
Marshal.FreeHGlobal(buffer);
}
ClosePrinter(printerHandle);
Console.WriteLine("Printer " + printerName+" is closed");
}
else
Console.WriteLine(" failed.");
}
[DllImport("winspool.drv", SetLastError = true)]
static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);
[DllImport("winspool.drv", CharSet = CharSet.Auto)]
static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport(
"winspool.drv",
EntryPoint = "GetJob",
SetLastError = true,
ExactSpelling = false,
CallingConvention = CallingConvention.StdCall)]
private static extern bool GetJob
([InAttribute()] IntPtr hPrinter,
[InAttribute()] UInt32 JobId,
[InAttribute()] UInt32 Level,
[OutAttribute()] IntPtr pJob,
[InAttribute()] UInt32 cbBuf,
[OutAttribute()] out UInt32 pcbNeeded);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct JOB_INFO_2
{
public UInt32 JobId;
public IntPtr pPrinterName;
public IntPtr pMachineName;
public IntPtr pUserName;
public IntPtr pDocument;
public IntPtr pNotifyName;
public IntPtr pDatatype;
public IntPtr pPrintProcessor;
public IntPtr pParameters;
public IntPtr pDriverName;
public IntPtr pDevMode;
public IntPtr pStatus;
public IntPtr pSecurityDescriptor;
public UInt32 Status;
public UInt32 Priority;
public UInt32 Position;
public UInt32 StartTime;
public UInt32 UntilTime;
public UInt32 TotalPages;
public UInt32 Size;
public SYSTEMTIME Submitted;
public UInt32 Time;
public UInt32 PagesPrinted;
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DEVMODE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
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 = 32)]
public string dmFormName;
public short dmLogPixels;
public int dmBitsPerPel;
public int dmPelsWidth;
public int dmPelsHeight;
public int dmDisplayFlags;
public int dmDisplayFrequency;
}
}
}
I am able to send special keys on local machine but the same thing is not working on remote machine. I referred to many articles but could not find the code to send special keys to remote desktop connection. Please help on this. Below is the code.
static void Main(string[] args)
{
Thread.Sleep(3000);
//char[] keyboardStrokes = { (char)Keys.LWin, (char)Keys.R };
char[] keyboardStrokes = { (char)Keys.LMenu, (char)Keys.F4 };
SendData(keyboardStrokes);
}
struct INPUT
{
public INPUTType type;
public INPUTUnion Event;
}
[StructLayout(LayoutKind.Explicit)]
struct INPUTUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public short wVk;
public short wScan;
public KEYEVENTF dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
enum INPUTType : uint
{
INPUT_KEYBOARD = 1
}
[Flags]
enum KEYEVENTF : uint
{
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
SCANCODE = 0x0008,
UNICODE = 0x0004
}
[DllImport("user32.dll", SetLastError = true)]
static extern UInt32 SendInput(int numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
[DllImport("user32.dll")]
static extern IntPtr GetMessageExtraInfo();
private static void SendData(char[] c)
{
ProcessKey(c);
}
private static void ProcessKey(char[] key)
{
// create input events as unicode with first down, then up
INPUT[] inputs = new INPUT[key.Length + 1];
for (int i = 0; i < key.Length; i++)
{
inputs[i].type = INPUTType.INPUT_KEYBOARD;
inputs[i].Event.ki.dwFlags = KEYEVENTF.UNICODE;
inputs[i].Event.ki.wScan = (short)key[i];
inputs[i].Event.ki.wVk = (short)key[i];
}
//Thread.Sleep(3000);
inputs[key.Length].type = INPUTType.INPUT_KEYBOARD;
inputs[key.Length].Event.ki.dwFlags = KEYEVENTF.KEYUP;
inputs[key.Length].Event.ki.dwExtraInfo = GetMessageExtraInfo();
// inputs[key.Length].Event.ki.wScan =
// inputs[key.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
uint cSuccess = SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
if (cSuccess != inputs.Length)
{
throw new Win32Exception();
}
}
Thanks in advance.
Finally I am able to send most of the special keys to remote machine by using following code. The only issue is that special keys remain pressed after the operation is completed. please let me know how to release the special keys.
class Program
{
static void Main(string[] args)
{
Thread.Sleep(3000);
int[] keyboardStrokes = { (int)Keys.LMenu, (int)Keys.Tab, (int)Keys.Tab };
ProcessKey(keyboardStrokes);
Console.Read();
}
struct INPUT
{
public INPUTType type;
public INPUTUnion Event;
}
[StructLayout(LayoutKind.Explicit)]
struct INPUTUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public KEYEVENTF dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
enum INPUTType : uint
{
INPUT_KEYBOARD = 1
}
[Flags]
enum KEYEVENTF : uint
{
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
SCANCODE = 0x0008,
UNICODE = 0x0004
}
[DllImport("user32.dll", SetLastError = true)]
static extern UInt32 SendInput(int numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
[System.Runtime.InteropServices.DllImport("user32.dll")]
internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
private static void ProcessKey(int[] key)
{
INPUT[] inputs = new INPUT[key.Length + 1];
for (int i = 0; i < key.Length; i++)
{
uint skey = MapVirtualKey((uint)key[i], (uint)0x0);
inputs[i].type = INPUTType.INPUT_KEYBOARD;
inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
inputs[i].Event.ki.wScan = (ushort)skey;
}
inputs[key.Length].type = INPUTType.INPUT_KEYBOARD;
inputs[key.Length].Event.ki.dwFlags = KEYEVENTF.UNICODE;
inputs[key.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
uint cSuccess = SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
}
}
I have a C api and I am using p/invoke to call a function from the api in my C# application. The function signature is:
int APIENTRY GetData (CASHTYPEPOINTER cashData);
Type definitions:
typedef CASHTYPE* CASHTYPEPOINTER;
typedef struct CASH
{
int CashNumber;
CURRENCYTYPE Types[24];
} CASHTYPE;
typedef struct CURRENCY
{
char Name[2];
char NoteType[6];
int NoteNumber;
} CURRENCYTYPE;
How would be my C# method signature and data types?
Thank you.
You need to specify the array sizes using SizeConst:
using System;
using System.Runtime.InteropServices;
public static class MyCApi
{
[StructLayout(LayoutKind.Sequential)]
public struct CASHTYPE
{
public int CashNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
public CURRENCYTYPE[] Types;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct CURRENCYTYPE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string Name;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)]
public string NoteType;
public int NoteNumber;
}
[DllImport("MyCApi.dll")]
public static extern int GetData(ref CASHTYPE cashData);
}
I think it may look like this
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct CASH{
public int CashNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
public CURRENCY Types[24];
}
[ StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct CURRENCY {
[MarshalAs( UnmanagedType.ByValTStr, SizeConst=2 )]
public string Name;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst=6 )]
public string NoteType;
public int NoteNumber;
}
class Wrapper {
[DllImport("my.dll")]
public static extern int GetData(ref CASH cashData}
}