C# change desktop wallpaper with winapi - c#

I'd like to change my desktop wallpaper. To do so I've written following code, but it doesn't work:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Microsoft.Win32;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Background bg = new Background();
bg.DoSomething();
}
}
class Background
{
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam,
string pvParam, uint fWinIni);
private const uint SPI_SETDESKWALLPAPER = 0x0014;
private const uint SPIF_UPDATEINIFILE = 0x01;
private const uint SPIF_SENDWININICHANGE = 0x02;
private string pathtofiles;
private string[] filename;
private int count, o, ui;
private Object thisLock = new Object();
public Background()
{
pathtofiles = #"C:\Users\Mine\Desktop\Test\";
filename = new string[150];
count = 0;
o = 0;
ui = 0;
}
public void DoSomething()
{
System.IO.DirectoryInfo ParentDirectory = new System.IO.DirectoryInfo(#"C:\Users\Mine\Desktop\Test\");
foreach (System.IO.FileInfo f in ParentDirectory.GetFiles())
{
if (f.Name.EndsWith(".jpg"))
{
filename[count] = f.Name;
count++;
}
if (f.Name.EndsWith(".png"))
{
filename[count] = f.Name;
count++;
}
if (f.Name.EndsWith(".bmp"))
{
filename[count] = f.Name;
count++;
}
}
count = 0;
foreach (string s in filename)
{
if (System.IO.File.Exists(pathtofiles + s))
{
System.IO.Stream BitmapStream = System.IO.File.Open(pathtofiles + s, System.IO.FileMode.Open);
System.Drawing.Image img = System.Drawing.Image.FromStream(BitmapStream);
System.Drawing.Bitmap mBitmap = new System.Drawing.Bitmap(img);
mBitmap.Save(#"C:\Users\Mine\Desktop\BmpSpeichern\00" + o + ".bmp");
o++;
}
}
System.IO.DirectoryInfo ParentDirectory2 = new System.IO.DirectoryInfo(#"C:\Users\Mine\Desktop\BmpSpeichern\");
foreach (System.IO.FileInfo f in ParentDirectory2.GetFiles())
{
if (f.Name.EndsWith(".bmp"))
{
filename[count] = f.Name;
count++;
}
}
if (!SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, #"C:\Users\Mine\Desktop\BmpSpeichern\" + filename[ui],
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE))
{
throw new Win32Exception();
}
}
}
}
First I copy the image files to another directory then convert them to .bmp data type. Works perfectly but the call to the WINAPI function SystemParametersInfo fails to change the wallpaper.
What am I doing wrong?

Related

Logitech G-KEY MACRO SDK(C#): can't enter the profile when I pressed my mouse button

SDK link: https://www.logitechg.com/en-us/innovation/developer-lab.html
It can create a profile in the LGS, but if I debug in GkeySDKCallback() it can't enter it when I pressed my mouse button.
I sent an email to Logitech Dev Support regarding this, but have not received anything back at this time.
Here is my code [2 files]
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Logitceh
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
bool usingCallback = false;
private void Form1_Load(object sender, EventArgs e)
{
this.TransparencyKey = Color.Red;
this.BackColor = Color.Red;
Start();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
OnDestroy();
}
void Start()
{
usingCallback = true;
if (usingCallback)
{
LogitechGSDK.logiGkeyCB cbInstance = new
LogitechGSDK.logiGkeyCB(this.GkeySDKCallback);
LogitechGSDK.LogiGkeyInitWithoutContext(cbInstance);
}
else
{
LogitechGSDK.LogiGkeyInitWithoutCallback();
}
}
void OnUpdate()
{
if (!usingCallback)
{
for (int index = 6; index <= LogitechGSDK.LOGITECH_MAX_MOUSE_BUTTONS; index++)
{
if (LogitechGSDK.LogiGkeyIsMouseButtonPressed(index) == 1)
{
// Code to handle what happens on gkey pressed on mouse
}
}
for (int index = 1; index <= LogitechGSDK.LOGITECH_MAX_GKEYS; index++)
{
for (int mKeyIndex = 1; mKeyIndex <= LogitechGSDK.LOGITECH_MAX_M_STATES;
mKeyIndex++)
{
if (LogitechGSDK.LogiGkeyIsKeyboardGkeyPressed(index, mKeyIndex) == 1)
{
// Code to handle what happens on gkey pressed on keyboard/headset
}
}
}
}
}
void GkeySDKCallback(LogitechGSDK.GkeyCode gKeyCode, String gKeyOrButtonString, IntPtr context)
{
if (gKeyCode.keyDown == 1)
{
if (gKeyCode.mouse == 1)
{
// Code to handle what happens on gkey released on mouse
}
else
{
// Code to handle what happens on gkey released on keyboard/headset
}
}
else
{
if (gKeyCode.mouse == 1)
{
// Code to handle what happens on gkey pressed on mouse
}
else
{
// Code to handle what happens on gkey pressed on keyboard
}
}
}
void OnDestroy()
{
//Free G-Keys SDKs before quitting the game
LogitechGSDK.LogiGkeyShutdown();
}
}
}
LogitechGSDK.cs
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Specialized;
using System;
public class LogitechGSDK
{
//G-KEY SDK
public const int LOGITECH_MAX_MOUSE_BUTTONS = 20;
public const int LOGITECH_MAX_GKEYS = 29;
public const int LOGITECH_MAX_M_STATES = 3;
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct GkeyCode
{
public ushort complete;
// index of the G key or mouse button, for example, 6 for G6 or Button 6
public int keyIdx
{
get
{
return complete & 255;
}
}
// key up or down, 1 is down, 0 is up
public int keyDown
{
get
{
return (complete >> 8) & 1;
}
}
// mState (1, 2 or 3 for M1, M2 and M3)
public int mState
{
get
{
return (complete >> 9) & 3;
}
}
// indicate if the Event comes from a mouse, 1 is yes, 0 is no.
public int mouse
{
get
{
return (complete >> 11) & 15;
}
}
// reserved1
public int reserved1
{
get
{
return (complete >> 15) & 1;
}
}
// reserved2
public int reserved2
{
get
{
return (complete >> 16) & 131071;
}
}
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void logiGkeyCB(GkeyCode gkeyCode,
[MarshalAs(UnmanagedType.LPWStr)]String gkeyOrButtonString, IntPtr context); // ??
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public static extern int LogiGkeyInitWithoutCallback();
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public static extern int LogiGkeyInitWithoutContext(logiGkeyCB gkeyCB);
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public static extern int LogiGkeyIsMouseButtonPressed(int buttonNumber);
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr LogiGkeyGetMouseButtonString(int buttonNumber);
public static String LogiGkeyGetMouseButtonStr(int buttonNumber)
{
String str =
Marshal.PtrToStringUni(LogiGkeyGetMouseButtonString(buttonNumber));
return str;
}
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public static extern int LogiGkeyIsKeyboardGkeyPressed(int gkeyNumber, int
modeNumber);
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper")]
private static extern IntPtr LogiGkeyGetKeyboardGkeyString(int gkeyNumber, int
modeNumber);
public static String LogiGkeyGetKeyboardGkeyStr(int gkeyNumber, int modeNumber)
{
String str =
Marshal.PtrToStringUni(LogiGkeyGetKeyboardGkeyString(gkeyNumber, modeNumber));
return str;
}
[DllImport(#"C:/DLL/LogitechGkeyEnginesWrapper", CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.Cdecl)]
public static extern void LogiGkeyShutdown();
}

Deleting JPEG Not Allowed(Used By Another Process)

Question Edited!! This is an example of compilabile files to help you find my problem!
I save some screenshots in a specific file.
When i use function DeleteFile() it should delete first the contents and then the folder but then i get "that icon.jpg is used by another process"!
(Either way to delete a folder it has to have no content!)
ImageExtensions.cs
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace name
{
static class ImageExtensions
{
public static void SaveToFile(Image image,string path,ImageFormat format)
{
using (var stream = File.OpenWrite(path))
{
image.Save(stream, format);
}
}
}
}
ScreenCapture.cs
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace name
{
public class ScreenCapture
{
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);
[StructLayout(LayoutKind.Sequential)]
private struct Rect
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetDesktopWindow();
public static Image CaptureDesktop()
{
return CaptureWindow(GetDesktopWindow());
}
public static Bitmap CaptureActiveWindow()
{
return CaptureWindow(GetForegroundWindow());
}
public static Bitmap CaptureWindow(IntPtr handle)
{
var rect = new Rect();
GetWindowRect(handle, ref rect);
var bounds = new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
var result = new Bitmap(bounds.Width, bounds.Height);
using (var graphics = Graphics.FromImage(result))
{
graphics.CopyFromScreen(new Point(bounds.Left, bounds.Top), Point.Empty, bounds.Size);
}
return result;
}
}
}
AnotherFile.cs (Uses PrintScreen() )
public void PrintScreen()
{
using (var image = ScreenCapture.CaptureDesktop())
{
ImageExtensions.SaveToFile(image, (file_images + ".jpg"), ImageFormat.Jpeg);
}
}
Form1.cs (Main)
using ...
using ...
namespace name{
public partial class Form1 : Form
{
const int MaxRetries = 3;
const int DelayBetweenRetries = 1000;
const int ERROR_SHARING_VIOLATION = unchecked((int)0x80070020);
string file_images = my_path_of_images_file;
Public Form1()
{
InitializeComponent();
CreateFile();
}
private void Form1_Load(object sender, EventArgs e){}
public void CreateFile()
{
if (!Directory.Exists(file_images))
{
DirectoryInfo di = Directory.CreateDirectory(file_images);
}
}
public void DeleteFiles()
{
string[] filesToDelete = Directory.GetFiles(file_images);
if (filesToDelete != null)
{
var files = filesToDelete.Where(x => Path.GetExtension(x).Contains(".jpg"));
foreach (var file in files)
{
var temp = file;
DeleteFile(temp); // Delete JPEG
}
}
Directory.Delete(file_images); // Delete Folder
}
public static void DeleteFile(string path)
{
for (int i = 0; i < MaxRetries; ++i)
{
try
{
File.Delete(path);
}
catch (IOException e)
{
// You may also sleep whatever the error is...
if (Marshal.GetHRForException(e) == ERROR_SHARING_VIOLATION)
{
Thread.Sleep(DelayBetweenRetries);
continue;
}
throw;
}
}
}
} // End Of Main.cs
} // End Of Namespace
I have had this problem before and I solved it by copying the image data from the filestream into a memorystream, then loading the image from it. Similarly with the saving the image. This way, even if Image keeps a reference to the source or saved stream, it is not a physical file.
A more complete solution: https://siderite.dev/blog/imagefromstream-or-imagefromfile.html
try:
using (var ms=new MemoryStream()) {
image.Save(ms,format);
File.WriteAllBytes(path,ms.ToArray());
}
I wrote this inline, so tweak it if it doesn't work exactly.

writing text to another window

I want to write text to the currently selected application but its writing junk and causing weird things to happen.
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Threading;
using System.Linq;
using System.Runtime.InteropServices;
namespace i_allbwn
{
class Program
{
static void Main(string[] args)
{
Thread.Sleep(500);
ActionWithChance.brif_allbwn();
Console.ReadKey();
}
}
class ActionWithChance
{
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
public const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag
public const int KEYEVENTF_KEYUP = 0x0002; //Key up flag
public static void brif_allbwn()
{
argraffu(new String[] {
"line1",
"line2",
"line3",
}
);
}
public static void allbwn(Byte[] Name)
{
for (int i = 0; i < Name.Length; i++)
{
Console.WriteLine("Writing " + (Char)Name[i]);
keybd_event((Byte)Name[i], 0, KEYEVENTF_EXTENDEDKEY, 0);
Thread.Sleep(10);
keybd_event((Byte)Name[i], 0, KEYEVENTF_KEYUP, 0);
}
}
public static void argraffu(String[] text)
{
foreach (String s in text)
{
allbwn(ToByteArray(s));
keybd_event((Byte)'\r', 0, KEYEVENTF_EXTENDEDKEY, 0);
Thread.Sleep(10);
keybd_event((Byte)'\r', 0, KEYEVENTF_KEYUP, 0);
}
}
public static Byte[] ToByteArray(String StringToConvert)
{
Char[] CharArray = StringToConvert.ToCharArray();
Byte[] ByteArray = new Byte[CharArray.Length];
for (int i = 0; i < CharArray.Length; i++)
{
ByteArray[i] = Convert.ToByte(CharArray[i]);
}
return ByteArray;
}
}
}
My functions for doing it are like this:
public const Int32 WM_CHAR = 0x0102;
public void SendKeys(string message)
{
foreach (char c in message)
{
int charValue = c;
IntPtr val = new IntPtr((Int32)c);
SendMessage(WindowHandle, WM_CHAR, val, new IntPtr(0));
}
}
Basically what I'm doing is getting the handle of the application, e.g:
Process proc = Process.GetProcessesByName("Notepad")[0];
Then getting the handle with proc.MainModule.Handle()
The Autoit library makes it really easy to interact with external windows.
Install the nuget package called AutoItX.Dotnet
Then it's just a matter of:
using AutoIt;
class Program
{
static void Main(string[] args)
{
AutoItX.Run("notepad.exe", null);
AutoItX.WinWait("Untitled - Notepad");
AutoItX.ControlSend("Untitled - Notepad", "", "[CLASSNN:Edit1]", "testing");
//ControlSend is the ideal way to send text, but you can also pretend text was typed into the keyboard:
AutoItX.Send("howdy pilgrim");
}
}

GetMessage() given an System.ExecutionEngineException

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Threading;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
public static extern
bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, int vk);
[DllImport("user32")]
public static extern
bool GetMessage(ref Message lpMsg, IntPtr handle, uint mMsgFilterInMain, uint mMsgFilterMax);
public const int MOD_ALT = 0x0001;
public const int MOD_CONTROL = 0x0002;
public const int MOD_SHIFT = 0x004;
public const int MOD_NOREPEAT = 0x400;
public const int WM_HOTKEY = 0x312;
public const int DSIX = 0x36;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
bool r = RegisterHotKey(Handle, 1, MOD_ALT, DSIX);
if (!r)
{
MessageBox.Show("can't do..");
return;
}
Message msg = new Message();
while (GetMessage(ref msg,IntPtr.Zero, 0, 0))
{
if (msg.message == WM_HOTKEY)
{
MessageBox.Show("do work..");
}
}
}
}
public class Message
{
public int message { get; set; }
}
}
when the target is pressed, I get the following error:
Exception of type 'System.ExecutionEngineException' was thrown.
what's is this? how to fix this? Thanks in advance.
This is doomed to failure. If you write your own message loop it will stop WinForms receiving any messages.
Instead, override the PreProcessMessage or WndProc functions.

C# ClickOnce SingleInstance project - how?

I want to create a program that uses ClickOnce for installation and registers a file-association,
and always only starts a single instance, so that if a file of that file extension is clicked again it will be sent to the first (already opened) program.
Does anybody know of a good code-example of how to do that ?
Please keep in mind the ClickOnce part - because that changes how one should handle the SingleInstance bit.
I guess this will help you: http://www.openwinforms.com/single_instance_application.html
You should use a Mutex to check if you application is running:
static void Main()
{
bool createdNew;
using (Mutex mutex = new Mutex(true, Application.ProductName, out createdNew))
{
mutex.ReleaseMutex();
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
else
{
using (Process currentProcess = Process.GetCurrentProcess())
{
foreach (Process process in Process.GetProcessesByName(currentProcess.ProcessName))
{
if (process.Id != currentProcess.Id)
{
User32.SetForegroundWindow(process.MainWindowHandle);
break;
}
}
}
}
}
}
The SetForegroundWindow:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
Same question over here: How can I build a single instance application using Click Once?
Try this on: http://northhorizon.net/2010/single-instance-clickonce/
I made an application that works this way. It uses Windows-messages to communicate. So in the seconde instance, you only need the Handle of the MainForm in the first instance. I saved this handle in a ClickOnce setting named hwnd.
using ProjectApplicationTemplate.Properties;
using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.Hosting;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace ProjectApplicationTemplate
{
static class Program
{
static Mutex mutex = new Mutex(true, guid());
static string guid()
{
// http://stackoverflow.com/questions/502303/how-do-i-programmatically-get-the-guid-of-an-application-in-net2-0
Assembly assembly = Assembly.GetExecutingAssembly();
var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0];
return attribute.Value;
}
static int MainWindowHandle
{
get
{
Settings.Default.Reload();
return Settings.Default.hwnd;
}
set
{
Settings sett = Settings.Default;
sett.hwnd = value;
sett.Save();
}
}
public static string GetFileName()
{
ActivationArguments a = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
// aangeklikt bestand achterhalen
string[] args = a == null ? null : a.ActivationData;
return args == null ? "" : args[0];
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
if (mutex.WaitOne(TimeSpan.Zero, true))
{
#region standaard
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
#endregion
MainForm frm = new MainForm();
MainWindowHandle = (int)frm.Handle;
Application.Run(frm);
MainWindowHandle = 0;
mutex.ReleaseMutex();
}
else
{
int hwnd = 0;
while (hwnd == 0)
{
Thread.Sleep(5);
hwnd = MainWindowHandle;
}
Win32.CopyDataStruct cds = new Win32.CopyDataStruct();
try
{
string data = GetFileName();
cds.cbData = (data.Length + 1) * 2; // number of bytes
cds.lpData = Win32.LocalAlloc(0x40, cds.cbData); // known local-pointer in RAM
Marshal.Copy(data.ToCharArray(), 0, cds.lpData, data.Length); // Copy data to preserved local-pointer
cds.dwData = (IntPtr)1;
Win32.SendMessage((IntPtr)hwnd, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
}
finally
{
cds.Dispose();
}
}
}
}
}
And in your MainForm
using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Windows.Forms;
namespace ProjectApplicationTemplate
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
OpenFile(Program.GetFileName());
}
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case Win32.WM_COPYDATA:
Win32.CopyDataStruct st = (Win32.CopyDataStruct)Marshal.PtrToStructure(m.LParam, typeof(Win32.CopyDataStruct));
string strData = Marshal.PtrToStringUni(st.lpData);
OpenFile(strData);
Activate();
break;
default:
// let the base class deal with it
base.WndProc(ref m);
break;
}
}
void OpenFile(string filename)
{
if (filename == "") return;
if (!File.Exists(filename)) return;
IDocument[] vensters = MdiChildren.Select(T => (IDocument)T).Where(T => T.CurrentFileName == filename).ToArray();
if (vensters.Length == 0)
{
ChildForm frm = new ChildForm();
frm.OpenFile(filename);
frm.MdiParent = this;
frm.Show();
}
else
{
vensters[0].Activate();
}
}
private void fileMenu_DropDownOpening(object sender, EventArgs e)
{
IDocument active = (IDocument)ActiveMdiChild;
if (active == null)
{
saveToolStripMenuItem.Enabled = false;
saveAsToolStripMenuItem.Enabled = false;
printToolStripMenuItem.Enabled = false;
printSetupToolStripMenuItem.Enabled = false;
printPreviewToolStripMenuItem.Enabled = false;
}
else
{
saveToolStripMenuItem.Enabled = active.Changed;
saveAsToolStripMenuItem.Enabled = true;
printToolStripMenuItem.Enabled = active.CanPrint;
printSetupToolStripMenuItem.Enabled = active.CanPrint;
printPreviewToolStripMenuItem.Enabled = active.CanPrint;
}
// fill the MRU-list
tmiOnlangsGeopend.DropDownItems.Clear();
string RecentFolder = Environment.GetFolderPath(Environment.SpecialFolder.Recent);
string[] bestanden = Directory.GetFiles(RecentFolder).Where(T => T.EndsWith(".text.lnk")).ToArray();
if (bestanden.Length == 0)
{
tmiOnlangsGeopend.DropDownItems.Add(new ToolStripMenuItem(Properties.Resources.NoRecent) { Enabled = false });
}
else
{
foreach (string bestand in bestanden.OrderBy(T => File.GetLastWriteTime(T)).Reverse())
{
ToolStripMenuItem tmi = new ToolStripMenuItem(Path.GetFileNameWithoutExtension(bestand.Substring(0, bestand.Length - 4)));
tmi.Click += delegate { OpenFile(ResolveShortCut(bestand)); };
tmiOnlangsGeopend.DropDownItems.Add(tmi);
}
}
}
string ResolveShortCut(string shc)
{
// Add Reference -> COM -> Windows Script Host Object Model
if (File.Exists(shc))
{
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
IWshRuntimeLibrary.IWshShortcut link = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(shc);
return link.TargetPath;
}
else
{
return "";
}
}
}
}
Win32.cs
using System;
using System.Runtime.InteropServices;
namespace ProjectApplicationTemplate
{
public partial class Win32
{
public const int WM_COPYDATA = 0x004A;
public struct CopyDataStruct : IDisposable
{
public IntPtr dwData;
public int cbData;
public IntPtr lpData;
public void Dispose()
{
if (this.lpData != IntPtr.Zero)
{
LocalFree(this.lpData);
this.lpData = IntPtr.Zero;
}
}
}
/// <summary>
/// The SendMessage API
/// </summary>
/// <param name="hWnd">handle to the required window</param>
/// <param name="Msg">the system/Custom message to send</param>
/// <param name="wParam">first message parameter</param>
/// <param name="lParam">second message parameter</param>
/// <returns></returns>
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref CopyDataStruct lParam);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LocalAlloc(int flag, int size);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LocalFree(IntPtr p);
}
}
If anyone wants some more information about this:
http://pieterjan.pro/?a=Projecten_csharp_DrawIt.php
And this one is a c# template featuring loads of stuff:
- single-instance application with file-associations
- Localization (at runtime as well)
- MDI and interface for traversing the user commands
- Checking for updates
- Most-recently used list
http://pieterjan.pro/Projecten/csharp/ProjectApplicationTemplate.zip
You could do something similar to this:
using System.Diagnostics;
namespace Foo
{
class Bar
{
static void Main(string[] args)
{
Process p = Process.GetCurrentProcess();
Process [] processSearch = Process.GetProcessesByName(p.ProcessName);
if (processSearch.Length > 1)
{
return;
}
}
}
}

Categories

Resources