I am trying to change the ComputerName on a windows machine. I am having a very strange result.
The Code that I'm using is:
public class MachineService
{
[DllImport("Kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetComputerNameA([MarshalAs(UnmanagedType.LPStr)] string computerName);
[DllImport("Kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetComputerName([MarshalAs(UnmanagedType.LPStr)] string computerName);
[DllImport("Kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetComputerNameEx(ComputerNameFormat NameType, [MarshalAs(UnmanagedType.LPStr)] string computerName);
public static bool ChangeName(string name)
{
var envVar = SetComputerName(name);
var ex = SetComputerNameEx(ComputerNameFormat.ComputerNamePhysicalNetBIOS, name);
return envVar && ex;
}
}
It does set the Environmental Variable ComputerName but it doesn't set the name of the device. please see the images below.
EDIT
It has changed the registry.
If I read the documentation correctly you should:
be using ComputerNamePhysicalDnsHostname instead of ComputerNamePhysicalNetBIOS
and you should NOT call SetComputerName before SetComputerNameEx
Related
I want to attach a console to an monogame application. I used .Net Framework at first and everything worked fine, then I switched to .Net Core 3.1 and the console stopped attaching to the process.
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool AttachConsole(int dwProcessId);
[DllImportAttribute("kernel32.dll", SetLastError = true, EntryPoint = "AllocConsole")]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
private static extern bool AllocConsole();
[DllImportAttribute("kernel32.dll", SetLastError = true, EntryPoint = "GetStdHandle")]
private static extern IntPtr GetStdHandle(Int32 nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool FreeConsole();
[DllImport("kernel32.dll", EntryPoint = "GetLastError")]
private static extern int GetLastError();
private void InitializeConsole() {
if (AttachConsole(Process.GetCurrentProcess().Id) && AllocConsole()) {
GetStdHandle(Process.GetCurrentProcess().Id);
_isInitializeConsole = true;
} else {
_isInitializeConsole = false;
throw new Exception($"Console alloc error code: {GetLastError()}");
}
}
When trying to attach a console from the AttachConsole method, I get result "false" and last error code - 5 (Access is denied). I ran the application as administrator and getting error code - 6 (The handle is invalid).
Is there a way to fix this error?
I am trying to wrapper a dll that are in some cloud directory.
private SafeLibraryHandle sevenZipSafeHandle;
public SevenZipHandle(string sevenZipLibPath)
{
this.sevenZipSafeHandle = Kernel32Dll.LoadLibrary(sevenZipLibPath);
if (this.sevenZipSafeHandle.IsInvalid)
{
throw new Win32Exception();
}
}
}
internal static class Kernel32Dll
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern SafeLibraryHandle LoadLibrary([MarshalAs(UnmanagedType.LPTStr)] string lpFileName);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern IntPtr GetProcAddress(SafeLibraryHandle hModule, [MarshalAs(UnmanagedType.LPStr)] string procName);
[SuppressUnmanagedCodeSecurity]
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool FreeLibrary(IntPtr hModule);
}
I am validating a dll file, but if I use :
sevenZipLibPath = “c:/temp/file.dll”
it works fine.
But if use some file that is on the internet like:
sevenZipLibPath = “"http://any.blob.core.windows.net/files/file.dll”
it does not work.
How can I check a DLL file from some cloud drive in that situation?
The LoadLibrary function
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
Only supports filepaths, not urls.
So download it first to a temporary location. You can also do that in code using the webclient class.
A simple example:
https://stackoverflow.com/a/525372/4640588
Edit - Example using the paths you provided
using (WebClient client = new WebClient())
{
client.DownloadFile(
"http://any.blob.core.windows.net/files/file.dll",
"c:/temp/file.dll");
}
Validate it, then delete it afterwards.
I am having trouble implementing an answer I got here!, Can anyone help me access this private static class?
namespace VEParameterTool
{
class ProcessorPlugIn
{
private static class UnsafeNativeMethods
{
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", SetLastError = true)]
static extern bool FreeLibrary(IntPtr hModule);
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate ErrorCode ProcessorFunction(ref IntPtr pRx);
IntPtr hLib = UnsafeNativeMethods.LoadLibrary("Processor.dll");
}
}
When I try to LoadLibrary, I get the error about protection levels:
'VEParameterTool.ProcessorPlugIn.UnsafeNativeMethods.LoadLibrary(string)' is inaccessible due to its protection level
I have searched for the solution but cant see anything to do with static classes.
Any hep would be greatly appreciated.
Andy
Why are you attempting to declare a private static class? The only method I can think of potentially being able to access information within the class is if you were to make it a nested private static class with public methods - and based on the code posted that is not the case.
Private means just that - it cannot be accessed from outside. Read more about access modifiers here: http://msdn.microsoft.com/en-us/library/ms173121.aspx
See here for an example of a private static class implementation:
https://dotnetfiddle.net/Lyjlbr
using System;
public class Program
{
public static void Main()
{
Bar.DoStuff();
// Bar.DoOtherStuff(); // Cannot be done due to protection level
Bar.DoStuffAndOtherStuff(); // note that this public static method calls a private static method from the inner class
}
private static class Bar
{
public static void DoStuff()
{
Console.WriteLine("Test");
}
public static void DoStuffAndOtherStuff()
{
DoStuff();
DoOtherStuff();
}
private static void DoOtherStuff()
{
Console.WriteLine("other stuff");
}
}
}
EDIT: apparently you can also use reflection to access private classes/members/functions, but I don't know much about it. See here: Why can reflection access protected/private member of class in C#?
You can leave the inner class private, making it only accessible to the ProcessorPlugIn class, but you have to make the methods public.
private static class UnsafeNativeMethods
{
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32", SetLastError = true)]
public static extern bool FreeLibrary(IntPtr hModule);
}
These methods will be only accessible from where their containing class can be accessed, in this example, ProcessorPlugIn.
I have a buggy third-party DLL files that, after some time of execution, starts throwing the access violation exceptions. When that happens I want to reload that DLL file. How do I do that?
Try this
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);
//Load
IntPtr Handle = LoadLibrary(fileName);
if (Handle == IntPtr.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
throw new Exception(string.Format("Failed to load library (ErrorCode: {0})",errorCode));
}
//Free
if(Handle != IntPtr.Zero)
FreeLibrary(Handle);
If you want to call functions first you must create delegate that matches this function and then use WinApi GetProcAddress
[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
IntPtr funcaddr = GetProcAddress(Handle,functionName);
YourFunctionDelegate function = Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate )) as YourFunctionDelegate ;
function.Invoke(pass here your parameters);
Create a worker process that communicates via COM or another IPC mechanism. Then when the DLL dies, you can just restart the worker process.
Load the dll, call it, and then unload it till it's gone.
I've adapted the following code from the VB.Net example here.
[DllImport("powrprof.dll")]
static extern bool IsPwrHibernateAllowed();
[DllImport("kernel32.dll")]
static extern bool FreeLibrary(IntPtr hModule);
[DllImport("kernel32.dll")]
static extern bool LoadLibraryA(string hModule);
[DllImport("kernel32.dll")]
static extern bool GetModuleHandleExA(int dwFlags, string ModuleName, ref IntPtr phModule);
static void Main(string[] args)
{
Console.WriteLine("Is Power Hibernate Allowed? " + DoIsPwrHibernateAllowed());
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
private static bool DoIsPwrHibernateAllowed()
{
LoadLibraryA("powrprof.dll");
var result = IsPwrHibernateAllowed();
var hMod = IntPtr.Zero;
if (GetModuleHandleExA(0, "powrprof", ref hMod))
{
while (FreeLibrary(hMod))
{ }
}
return result;
}
How can I bring a console application window to front in C# (especially when running the Visual Studio debugger)?
It's hacky, it's horrible, but it works for me (thanks, pinvoke.net!):
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
public class Test
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint="FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr zeroOnly, string lpWindowName);
public static void Main()
{
string originalTitle = Console.Title;
string uniqueTitle = Guid.NewGuid().ToString();
Console.Title = uniqueTitle;
Thread.Sleep(50);
IntPtr handle = FindWindowByCaption(IntPtr.Zero, uniqueTitle);
if (handle == IntPtr.Zero)
{
Console.WriteLine("Oops, cant find main window.");
return;
}
Console.Title = originalTitle;
while (true)
{
Thread.Sleep(3000);
Console.WriteLine(SetForegroundWindow(handle));
}
}
}
This is what I would do.
[DllImport("kernel32.dll", ExactSpelling = true)]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
public void BringConsoleToFront()
{
SetForegroundWindow(GetConsoleWindow());
}
Get two monitors (at least) and open VisualStudio in the secondary monitor. When you run your app from within VisualStudio it will start up by default on the primary monitor. Since it's the last app to be opened, it starts on top and changing over to VisualStudio doesn't affect it. Works for me anyway.
If you don't already have a second monitor, IMHO, you should.