ExitWindowsEx windows 7 shutdown does not work - winapi

I am trying to get a Windows 7 machine to reboot from a C# WPF application. To this extent I've added the following code (I used an enum, but to keep the code short I'm just inserting the constants here):
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool ExitWindowsEx(ExitWindows uFlags, ShutdownReason dwReason);
public static void Reboot() {
ExitWindowsEx(0x02, 0x0)
}
On Windows 7 machines this does absolutely nothing (for me anyway). Changing the 0x2 (reboot) to 0x0 (logoff) does make the code logoff the current user, but the Reboot code doesn't seem to work.
Using the GetLastError API call didn't do much either. It just says something about the function having completed successfully.
For now I just cope by calling the shutdown command with /r /f, but I'd prefer to be able to call a Windows API directly from my application, so any help would be greatly appreciated.

You are not checking for errors correctly. Only check if the function returns false, do not pinvoke GetLastError(), use Marshal.GetLastWin32Error() instead. Best way:
public static void Reboot() {
if (!ExitWindowsEx(0x02, 0x0)) {
throw new System.ComponentModel.Win32Exception();
}
}
With high odds that you'll find out that you don't have enough privileges to reboot the machine. AdjustTokenPrivileges required, check the MSDN article.

Related

how to sign out from windows 10 program in uwp?

how to log off(sign out) windows 10 using uwp?
I have do in win-forms but codes are not working in uwp.
[DllImport("user32.dll")]
public static extern int ExitWindowsEx(int operationFlag, int rationReason);
private void button_Click(object sender, RoutedEventArgs e)
{
//Application.Current.Exit();
ExitWindowsEx(0, 0);
}
In non-UWP programme You can create a new process and run
%windir%\System32\shutdown.exe /l /t 0
But this is not available to UWP programmes. Check out the Stack Overflow link here for another take on this problem. But it looks like you are out of luck.
As i see your code above , you are actually closing the application. In UWP , Application works on states like Activated, Running, Suspended or Exited
If you want to log out from the application , it means that you would like to wipe of all user data and his Navigation History.
Make A function that clears the NavigationTrace and once the NavigationEntry is cleared , navigate the user to the login screen/home page

How to receive simplest Windows message on UWP XAML MVVM app?

My big-picture problem:
I need to send a signal from a Windows 10 desktop app (or a service, really) to a UWP XAML MVVM app on the same OS instance / machine.
I was using named semaphores in the global namespace, but these don't work at all on UWP (by design, for security reasons maybe). No joy.
I tried UWP sockets, and this works with the UWP as listener only if the client is on a remote machine. Is this a security design decision, too? No idea. Exempting the app from loopback restriction does not help, since that only applies if the UWP app is the client making the request. No joy.
OK, so I'm left with sending a Windows message to the specific window on the OS...
My test app is the AdventureWorks sample for UWP on GitHub. How do I get this to handle a Windows message sent from a different process? I'm stumped.
Below is my test client code.
QUESTION:
How do I handle this message in AdventureWorks? It's important to keep code changes to a minimum, but currently I'm stuck and have no idea to proceed. (It seems to be a tightly-held secret...)
Please help! Sample code please.
class Program
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, String lpWindowName);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, uint wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern uint RegisterWindowMessage(string lpString);
[DllImport("kernel32.dll")]
static extern uint GetLastError();
static void Main(string[] args)
{
const string lpClassName = "ApplicationFrameWindow";
const string lpWindowName = "AdventureWorks.Shopper";
IntPtr hwnd = FindWindow(lpClassName, lpWindowName);
uint messageId = RegisterWindowMessage("MetaAutomationMessage");
int sendMessageResult = SendMessage(hwnd, messageId, IntPtr.Zero, IntPtr.Zero);
Console.WriteLine(string.Format("Message result is '{0}', ", sendMessageResult));
uint lastError = GetLastError();
Console.WriteLine(string.Format("GetLastError result is '{0}', ", lastError));
}
}
Windows 10 UWP App service communication can be one of the options to send set of key-values between UWP apps.
Reference:
https://msdn.microsoft.com/en-us/windows/uwp/launch-resume/how-to-create-and-consume-an-app-service
The UWP app is sandboxed, so you can't send or receive messages, etc. by design to a Win32 app.
There are somewhat potentially less desirable options like enabling loopback communications over a local socket: https://stackoverflow.com/a/33263253/95190 (which maybe is what you tried -- it's not clear).
However a UWP app may not be the best platform choice today if you need to communicate from a locally installed service to your Universal app.
There are some ways of launching an app and providing some data as part of the launch, but a Win32 service should not launch interactive user processes (so, it wouldn't be a good way to pass data either).
You may want to consider building your app as a WPF app if communication with a Win32 app/service is needed.

Running EXE application in GINA beofe login screen (Command line)

I have created a Credential Launcher for Windows 7 and was able to run Windows application after the Tile button click event, it was very easy.
I added a few registry settings and *pbAutoLogon = FALSE;.
However now i am now trying to do the same for Windows XP.
Which function I should target or how to achieve the same results ?
I see you tagged your question with "Gina", so I guess you know that Credential Providers do not exist on XP.
Your answer depends on when exactly you want to run that program, especially with regards to the secure attention sequence (SAS, or when a user press CTRL-ALT-Delete)
Before the SAS, use WlxDisplaySASNotice
After the SAS, use WlxLoggedOutSAS
Since you don't want to write a whole GINA yourself, you could use a custom Gina that wraps msgina.dll. Here is one I wrote, you can find the original I started from in the Platform SDK.
Using that approch, you get a chance to execute code just before or just after certain events, like running your program after a successful logon, something like :
int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID * pProfile)
{
int result;
result = pfWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile);
if (result == WLX_SAS_ACTION_LOGON)
{
//We have a successful logon, let's run our code
run_my_custom_code();
}
return result;
}
There are some caveats, though :
The code cannot block. Winlogon will wait, but your users might not. Spanw a process and let it run.
Your program will be running with SYSTEM privileges, which is a security risk. Sandboxing your process could be hard. If you can't break out of it, don't assume nobody can...

Unmanaged Exports (DLLExport) crashes

I'm using RGiesecke DLLExport library to produce a C# DLL that can be dynamically loaded from legacy application built on VC6. It exported methods and they were called from VC6 code. No problems. However, as long as I tried to declare a variable as of any one of my .net classes, it crashed.
//I tried CallingConvention = CallingConvention.StdCall too
[DllExport(CallingConvention = CallingConvention.Winapi)]
static void GetDwgReferences(string fileName)
{
//OK: inialize System classes of .net
DateTime dateTime = DateTime.Now;
//crashing here: declare a variable of my static class (.net assemebly)
//SafeString safeString;
//crashing here: declare a variable of my class (.net assemebly)
//Email email;
//crashing here: initialize an object of my class (.net assemebly)
//DwgXrefs dwgXrefs = new DwgXrefs();
//crashing here by declcare a variable of third-party library (.net assemebly)
//ExSystemServices _serv;
}
What's wrong? Please help.
I had a similar problem here trying to use unmanaged exports with Metatrader to load associated managed dlls.
After some digging I think I have found the problem. The app domain is probably not where you would expect it to be, the CLR is trying to resolve your assembly but failing with a nondescript error. In my case the app domain was actually executing in the directory of the host application, so I assume this is always the case.
What I would suggest you do is build a bare dll with no dependencies, and place in something such as the following:
static void Initialize()
{
SimpleLog.WriteLog("App -" + AppDomain.CurrentDomain.BaseDirectory);
}
[DllExport("Test", CallingConvention = CallingConvention.StdCall)]
public static void Test()
{
Initialize();
}
I am not sure but I think you possibly cannot use a static constructor here?
In the log you should see the executing directory for that domain. If you put your assemblies here it (hopefully) should work. It has fixed the problem for me here. I guess the next question is can we change the domain at runtime as I might not want to put these assemblies here.
Have a google if you need the source code for a simple logger - obviously do not use a third party logging framework with dll dependencies!
I think mine is an adaptation of this one:
http://www.codeproject.com/Articles/80175/Really-Simple-Log-Writer
As the other answer stated, it is difficult to know what error C# is throwing without explicitly catching the error in a try / catch block within each method of a C# dll.
You likely need to export as CallingConvention.StdCall and additionally marshal the incoming string as an unmanaged LPWStr type:
[DllExport(CallingConvention = CallingConvention.StdCall)]
static void GetDwgReferences([MarshalAs(UnmanagedType.LPWStr)] string fileName)
{
}
Please see Code to Export C# DLL to Metatrader Build 600+ for a working example using Robert Giesecke's C# Project Template for Unmanaged Exports to export a C# dll to a legacy application (MT4).
Additionally, you might find Native and .NET Interopability interesting though it is mostly geared toward accessing native code from within .NET.

VB6 App using COM Interop works fine in IDE, but compiled EXE crashes

I am currently working on an app in VB6 that uses COM Interop libraries written in C# using the .NET 2.0 framework.
I used regasm.exe to register the tlb files from the .NET dlls using the /codebase switch. I was then able to successfully build and run the application in the VB6 IDE with no issues. The .NET code uses a config file, so I added it to the VB6 directory and it read from the configurations fine.
However, I then compiled an EXE file from the project an ran it on the same machine as the IDE is running on. I coupled the EXE with the config file just as I had done in debugging with the VB6.EXE, but when the app executes the first call to a method in one of the .NET classes, it throws a run-time error indicating an "Automation Error".
In my Declarations, I instantiate the following objects from the .NET classes, which seems to work fine.
Private objSession As New Session
Private curFolder As Folder
Private colFolderTemplates As New FolderTemplateCollection
Private objLicense As New License
However, the Automation Error comes up at runtime when the first line is executed:
Call objSession.Configuration.Configure(connectionString)
I tried adding the .NET dlls to the same directory as the Release EXE and re-registering the tlb files, but it did not help. Any suggestions on what I could check?
Ok, shot in the dark. Things to try:
Explicitly new up the Session object (as well as License and FolderTemplateCollection):
Private objSession as Session
Set objSession = new Session
Automation error indicates that the GUIDs from the .NET assembly are not persisting. To do so, do this in your C# code - this then guarantees that all Interfaces/Classes/Virtual tables persist, no matter how many times you compile your c# code:
[Guid("9AC71CA7-6F82-44A3-9ABE-75354B514A46")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IManager
{
[DispId(1)]
void Display(ADODB.Recordset recordSet);
[DispId(2)]
void Close();
[DispId(3)]
string UserName { get; set; }
[DispId(4)]
string Password { get; set; }
[DispId(5)]
string Database { get; set; }
[DispId(6)]
string Server { get; set; }
[DispId(7)]
ICriteria Criteria { get; set; }
}
[Guid("B9BB5B84-8FBD-4095-B846-EC072163ECD3")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyApp.Manager")]
public class Manager : IManager
{
void Display(ADODB.Recordset recordSet)
{
}
...
}

Resources