I want to write a program in C# that recognize now computer connected to internet or not by C#.
Would you help me how to do that, I have no idea about it,because I didnt work network in C#.
one more question,how I can run a program from c# and sent argument also?
Use Microsoft's InternetGetConnectedState function.
You can call it with P/Invoke:
using System;
using System.Runtime.InteropServices;
namespace ConnectionState
{
internal class Program
{
[DllImport("wininet.dll", SetLastError = true)]
private static extern bool InternetGetConnectedState(out int lpdwFlags, int dwReserved);
private static void Main(string[] args)
{
int flags;
bool isConnected = InternetGetConnectedState(out flags, 0);
Console.WriteLine(string.Format("Is connected: {0} Flags:{1}", isConnected, flags));
Console.Read();
}
}
}
Related
I've recently been working on a little side project to see if I can get a little memory editing to work with PowerShell. I put together a small script in C# that doesn't require administrative privileges and when ran, gives you max coins and diamonds in Hill Climb Racing.
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace HCRtest2
{
public class Programmmm
{
public static void Main()
{
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, long lpBaseAddress, byte[] lpBuffer, uint nSize, out uint lpNumberOfBytesRead);
long BaseAddress;
IntPtr ProcessHandle;
Process process = Process.GetProcessesByName("HillClimbRacing")[0];
if (process.Handle.ToInt64() != 0L)
{
BaseAddress = process.MainModule.BaseAddress.ToInt64();
ProcessHandle = process.Handle;
uint num = 0U;
WriteProcessMemory(ProcessHandle, BaseAddress + 0x28CAD4, BitConverter.GetBytes(2147483647), 4U, out num);
WriteProcessMemory(ProcessHandle, BaseAddress + 0x28CAEC, BitConverter.GetBytes(2147483647), 4U, out num);
}
}
}
}
My challenge right now is to see if I can find a way to execute this code on my school laptop which doesn't have admin privileges or access to open unknown executables, but it does have access to PowerShell (nonadmin of course). I've been doing a lot of research but cant find a good way to port this script into PowerShell. If anyone has any good ideas please let me know because this is seriously getting on my nerves right now.
This website provides an answer on how to play c# within a powershell session.
$code = #"
using System;
namespace HelloWorld
{
public class Program
{
public static void Main(){
Console.WriteLine("Hello world!");
}
}
}
"#
Add-Type -TypeDefinition $code -Language CSharp
iex "[HelloWorld.Program]::Main()"
It's been a couple of months of on and off work, but I found out that everything has to be labeled as public and static, and along with that I was missing a method that was required to make sure the process would be properly opened, here's the working code that can be executed in Powershell.
$code = #"
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace HelloWorld
{
public class Program
{
public const int ProcessVMWrite = 0x0020;
public const int ProcessVMOperation = 0x0008;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool WriteProcessMemory
(
IntPtr hProcess,
long lpBaseAddress,
byte[] lpBuffer,
int nSize,
out int lpNumberOfBytesRead
);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess
(
int dwDesiredAccess,
bool bInheritHandle,
int dwProcessId
);
public static IntPtr Handle;
public static long BaseAddress;
public static void Main(){
Process process = Process.GetProcessesByName("HillClimbRacing")[0];
Handle = OpenProcess(ProcessVMOperation | ProcessVMWrite, false, process.Id);
BaseAddress = process.MainModule.BaseAddress.ToInt64();
int thingy = 0;
WriteProcessMemory(Handle, BaseAddress + 0x28CAD4L, BitConverter.GetBytes(2147483647), 4, out thingy);
WriteProcessMemory(Handle, BaseAddress + 0x28CAECL, BitConverter.GetBytes(2147483647), 4, out thingy);
}
}
}
"#
Add-Type -TypeDefinition $code -Language CSharp
iex "[HelloWorld.Program]::Main()"
I am trying to create a C# library that "embeds" a Ruby interpreter, using DllImport to execute C-Ruby functions.
public const string RUBY_DLL = #"msvcrt-ruby18";
[DllImport(RUBY_DLL, CallingConvention = CallingConvention.Cdecl)]
private static extern void ruby_init();
// ... Everything in between...
[DllImport(RUBY_DLL, CallingConvention = CallingConvention.Cdecl)]
private static extern void ruby_finalize();
This works perfectly fine, and I am quite able to import the functions and interact with Ruby, but only if using msvcrt-ruby18.dll, which is obviously outdated. I would like to use msvcrt-ruby240.dll, or even msvcrt-ruby19*.dll, but every attempt I make to do so fails. I created a variant that loads the functions with LoadLibrary and GetProcAddress, that way I could use any installed version of Ruby, but everything fails.
When using DllImport, I get the "DllNotFoundException", which seems to indicate a missing dependency of the Ruby dll somewhere. I have ensured that I am building under x86, and using x86 Ruby library, so this is not a BadImageFormat issue. When using the LoadLibrary, I can actually call ruby_init without an error in newer versions, but invoking rb_eval_string fails with anything other than msvcrt-ruby18.dll.
I am quite familiar with using P/Invoke, and am not asking "how" to link to them. I AM quite green when it comes to actually writing C code, or understanding exactly the the differences in builds of the msvcrt-ruby***.dll, static libraries, etc.
After extensive Google research, I cannot find one single example that links C# and Ruby that uses anything newer than msvcrt-ruby18.dll, and was hoping to gain some insight as to how I can and what I have to do. I am not opposed to compiling Ruby myself if that is required, but would really appreciate any tips on that if it is required, and what I would have to edit, etc.
EDIT:
Here's what I am doing.
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
public class RubyHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32")]
public static extern bool FreeLibrary(IntPtr hModule);
public RubyHandle(string rubyDllPath) : base(true)
{
SetHandle(LoadLibrary(rubyDllPath));
if (handle == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
}
public override bool IsInvalid
{
get => handle == IntPtr.Zero;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
return FreeLibrary(handle);
}
public static implicit operator IntPtr(RubyHandle rubyHandle)
{
return rubyHandle.DangerousGetHandle();
}
}
And to bind the functions...
[SuppressUnmanagedCodeSecurity]
public static class Ruby
{
public const string RUBY_DLL = #"C:\Ruby24\bin\msvcrt-ruby240.dll";
[DllImport("kernel32", SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
private static RubyHandle _rubyLib;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void VoidArgs0();
private static VoidArgs0 _ruby_init;
private static VoidArgs0 _ruby_finalize;
private static VoidArgs0 _ruby_show_version;
private static VoidArgs0 _ruby_show_copyright;
public static void Initialize(string rubyDllPath = null)
{
_rubyLib = new RubyHandle(rubyDllPath ?? RUBY_DLL);
ImportFunctions();
_ruby_init.Invoke();
}
private static void ImportFunctions()
{
_ruby_init = (VoidArgs0) ImportFunction<VoidArgs0>("ruby_init");
_ruby_finalize = (VoidArgs0) ImportFunction<VoidArgs0>("ruby_finalize");
_ruby_show_version = (VoidArgs0) ImportFunction<VoidArgs0>("ruby_show_version");
_ruby_show_copyright = (VoidArgs0) ImportFunction<VoidArgs0>("ruby_show_copyright");
}
private static object ImportFunction<T>(string functionName)
{
var ptr = GetProcAddress(_rubyLib, functionName);
if (ptr == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T));
}
public static void Release()
{
_ruby_finalize.Invoke();
_rubyLib.Dispose();
}
public static void ShowVersion()
{
_ruby_show_version.Invoke();
}
}
The error occurs right in the beginning, before it even gets started on the call to "LoadLibrary", I get the "Specified module was not found" error. I have also made sure that both "C:\Ruby24\bin\ruby_builtin_dlls" and "C:\Ruby24\bin" are included in PATH.
I am beating my head against a wall. I see no reason why this does not work...
OK, so finally figured this out, will post the answer here for anyone else who may stumble into a similar problem.
I ended up manually adding the directories for Ruby's dependencies via "AddDllDirectory":
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool AddDllDirectory(string lpPathName);
And then using "LoadLibraryEx" opposed to "LoadLibrary", and specifying the "LOAD_LIBRARY_SEARCH_DEFAULT_DIRS" flag.
[DllImport("kernel32", SetLastError = true)]
static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags);
[System.Flags]
enum LoadLibraryFlags : uint
{
DontResolveDllReferences = 0x00000001,
LoadIgnoreCodeAuthzLevel = 0x00000010,
LoadLibraryAsDatafile = 0x00000002,
LoadLibraryAsDatafileExclusive = 0x00000040,
LoadLibraryAsImageResource = 0x00000020,
LoadLibrarySearchApplicationDir = 0x00000200,
LoadLibrarySearchDefaultDirs = 0x00001000,
LoadLibrarySearchDllLoadDir = 0x00000100,
LoadLibrarySearchSystem32 = 0x00000800,
LoadLibrarySearchUserDirs = 0x00000400,
LoadWithAlteredSearchPath = 0x00000008
}
And then...
public static void Initialize(string rubyDllPath = null)
{
AddDllDirectory(#"C:\Ruby24\bin");
AddDllDirectory(#"C:\Ruby24\bin\ruby_builtin_dlls");
_rubyLib = new RubyHandle(rubyDllPath ?? RUBY_DLL);
ImportFunctions();
_ruby_init.Invoke();
}
Obviously the final product will do this dynamically, but this way successfully loads the library.
I'm running the following c# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.IO;
namespace TCLRunner
{
class Program
{
private static TclInterpreter interp;
static void Main(string[] args)
{
try
{
interp = new TclInterpreter();
//interp.evalScript(#"cd ..");
interp.evalScript(#"set a ""this is a""");
interp.evalScript(#"puts ""Free text""");
interp.evalScript(#"puts $a");
interp.evalScript(#"package require Tcl");
printResults();
interp.evalScript(#"package require http");
printResults();
//
//
// Shutdown and end connection
}
catch (Exception e)
{
Console.WriteLine("SocketException: {0}", e);
}
}
public static void printResults()
{
string result = interp.Result;
Console.WriteLine("Received: {0}", result);
}
}
public class TclAPI
{
[DllImport("tcl84.DLL")]
public static extern IntPtr Tcl_CreateInterp();
[DllImport("tcl84.Dll")]
public static extern int Tcl_Eval(IntPtr interp, string skript);
[DllImport("tcl84.Dll")]
public static extern IntPtr Tcl_GetObjResult(IntPtr interp);
[DllImport("tcl84.Dll")]
unsafe public static extern char* Tcl_GetStringFromObj(IntPtr tclObj, IntPtr length);
}
public class TclInterpreter
{
private IntPtr interp;
public TclInterpreter()
{
interp = TclAPI.Tcl_CreateInterp();
if (interp == IntPtr.Zero)
{
throw new SystemException("can not initialize Tcl interpreter");
}
}
public int evalScript(string script)
{
return TclAPI.Tcl_Eval(interp, script);
}
unsafe public string Result
{
get
{
IntPtr obj = TclAPI.Tcl_GetObjResult(interp);
if (obj == IntPtr.Zero)
{
return "";
}
else
{
return Marshal.PtrToStringAnsi((IntPtr)TclAPI.Tcl_GetStringFromObj(obj, IntPtr.Zero));
}
}
}
}
}
I get the following output:
Free text
this is a
Received: 8.4
Received: can't find package http
How comes it doesn't find http package?
When I try the same thing manually on tclsh, it works with no problems.
Thanks!
You need to initialize the library before calling Tcl_CreateInterp(). The library is initialized by calling Tcl_FindExecutable with the name of the binary running things as known, but that can be left as NULL relatively safely; it's the other things that (poorly-named) function does that matter, such as setting up where to find its libraries.
The correct declaration in C# is this (though that MarshalAs attribute is optional in this case):
[DllImport("tcl84.DLL")]
public static extern void Tcl_FindExecutable([MarshalAs(UnmanagedType.LPTStr)] string s);
And you invoke it like this, exactly once:
TclAPI.Tcl_FindExecutable(null);
(It's probably wisest to do so as part of a static constructor in the TclAPI class. Yes, it belongs that early.)
If that doesn't work (I really can't test!) you'll have to set up some environment variables. The key one will be TCL_LIBRARY which overrides the default location Tcl looks for its support scripts (including the http package), and you might need to set TCLLIBPATH as well. (Note that TCL_LIBRARY is there mainly to support pre-installation testing, but has a history of being set at the system level by Python other systems that ought not to. Beware!)
Again, this must be done prior to the Tcl_CreateInterp() call.
I'm very new to c# and I want to do a code that will logoff all users that logged to the pc.
I tried to do this:
System.Diagnostics.Process("shutdown", "/l");
But this didn't logged off all the users, this logged off only the user that I was running from it.
So how can I do this?
Use the WTSDisconnectSession() Windows API. See article here.
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
class Program
{
[DllImport("wtsapi32.dll", SetLastError = true)]
static extern bool WTSDisconnectSession(IntPtr hServer, int sessionId, bool bWait);
const int WTS_CURRENT_SESSION = -1;
static readonly IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
static void Main(string[] args)
{
if (!WTSDisconnectSession(WTS_CURRENT_SERVER_HANDLE,
WTS_CURRENT_SESSION, false))
throw new Win32Exception();
}
}
I try to change the hostname via kernel32.dll import and the function SetComputerName. SetComputerName function
Mainclass:
namespace Castell
{
class Program
{
private static string hostname { get; set; }
setHostname();
private static void setHostname()
{
hostname = "TEST123456789";
int errorcode = ImportDLL.SetComputerName(hostname);
Console.WriteLine(Marshal.GetLastWin32Error());
}
}
}
Import Class:
namespace Castell
{
class ImportDLL
{
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int SetComputerName(string hostname);
}
}
Result of the Marshal.GetLastWin32Error() is "6". So that means:
ERROR_INVALID_HANDLE
6 (0x6)
The handle is invalid.
Dont know whats wrong with the handle.
You are just doing it wrong. The return type of SetComputerName() is bool, not int. It returns false when the function failed. The hard rule in the winapi is that you should only ever obtain the error code when the function failed. Or to put it another way, Windows doesn't explicitly set the error code back to 0 when the function is successful. Only then use Marshal.GetLastWin32Error() to retrieve the error code. Otherwise done automatically by the Win32Exception class constructor. Which makes this code work:
public static void SetHostname(string hostname)
{
if (!SetComputerName(hostname)) {
throw new System.ComponentModel.Win32Exception();
}
}
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int SetComputerName(string hostname);