大家,我每秒有很多文件写入磁盘,我想禁用磁盘缓存以提高性能,我谷歌搜索找到解决方案:win32 CreateFile method with FILE_FLAG_NO_BUFFERING 和 How toempty /flush Windows READ disk cache in C#? 。
我写了一些代码来测试是否可以工作:
const int FILE_FLAG_NO_BUFFERING = unchecked((int)0x20000000);
[DllImport("KERNEL32", SetLastError = true, CharSet = CharSet.Auto, BestFitMapping = false)]
static extern SafeFileHandle CreateFile(
String fileName,
int desiredAccess,
System.IO.FileShare shareMode,
IntPtr securityAttrs,
System.IO.FileMode creationDisposition,
int flagsAndAttributes,
IntPtr templateFile);
static void Main(string[] args)
{
var handler = CreateFile(@"d:\temp.bin", (int)FileAccess.Write, FileShare.None,IntPtr.Zero, FileMode.Create, FILE_FLAG_NO_BUFFERING, IntPtr.Zero);
var stream = new FileStream(handler, FileAccess.Write, BlockSize);//BlockSize=4096
byte[] array = Encoding.UTF8.GetBytes("hello,world");
stream.Write(array, 0, array.Length);
stream.Close();
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试 P/Invoke C# 中的NotifyServiceStatusChange 事件来检查服务何时停止。我设法让它编译并运行,没有任何错误,但是现在,当我停止服务时,它似乎不想通知它 dead。有什么想法吗?您可以通过将此代码复制到空白控制台应用程序中来测试它;只需确保将“我的服务名称”替换为您的服务名称(下面有该字符串的两个实例)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
public delegate void StatusChanged(IntPtr parameter);
public class SERVICE_NOTIFY : MarshalByRefObject
{
public uint dwVersion;
public StatusChanged pfnNotifyCallback;
public IntPtr pContext;
public uint dwNotificationStatus;
public SERVICE_STATUS_PROCESS ServiceStatus;
public uint dwNotificationTriggered;
public IntPtr pszServiceNames;
};
public struct SERVICE_STATUS_PROCESS {
public uint dwServiceType;
public uint dwCurrentState;
public uint dwControlsAccepted;
public uint dwWin32ExitCode;
public …Run Code Online (Sandbox Code Playgroud) 我正在使用来自第 3 方供应商的 C API DLL。我遇到的问题是,我似乎找不到用于编组以下 C 代码的好模板:
API_Open( void ** handle );
API_Close( void * handle );
Run Code Online (Sandbox Code Playgroud)
调用被简化了,但句柄是一个 void *,它(在 C 中)API_Open作为 &handle传入调用,然后API_Close作为句柄传入。
我尝试在 C# 中做同样的事情,但无法弄清楚如何正确处理 Marshal。我的 C# 版本(最新尝试)是:
[DllImport("External.dll",EntryPoint="API_Open")]
public static extern int API_Open( out IntPtr handle );
[DllImport("External.dll",EntryPoint="API_Close")]
public static extern int API_Close( IntPtr handle );
public static int Wrapper_API_Open( ref Int32 handle )
{
int rc = SUCCESS;
// Get a 32bit region to act as our void**
IntPtr voidptrptr = Marshal.AllocHGlobal(sizeof(Int32)); …Run Code Online (Sandbox Code Playgroud) 我想确定指定进程是否启用了特定权限。
为了使这个问题更容易,示例目标进程将是当前进程,我将检查关闭本地系统的权限(以前使用AdjustTokenPrivileges功能启用)。
Then, I found the PrivilegeCheck function that seems can determine whether a specified set of privileges are enabled in an access token of a target process.
I think that I focused on the wrong direction, because seems that the PrivilegeCheck function needs impersonation, so now I'm facing another neverending trial-and-error phase trying the GetTokenInformation function, which seems the proper function to realize this task.
The problem I have is that when …
我有一个非常著名的使用(丑陋的)消息进行进程间数据交换的设置WM_COPYDATA。这不是我的决定,我必须在遗留应用程序中支持它。
const uint WM_COPYDATA = 0x004A;
[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public uint dwData;
public int cbData;
public IntPtr lpData;
}
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr hwnd, uint msg, IntPtr wparam, ref COPYDATASTRUCT lparam);
Run Code Online (Sandbox Code Playgroud)
如果我只发送一个简单的结构,而不附加附加数据,它就可以正常工作:
COPYDATASTRUCT container;
container.dwData = 42;
container.cbData = 0;
container.lpData = IntPtr.Zero;
SendMessage(myHwnd, WM_COPYDATA, IntPtr.Zero, ref container);
Run Code Online (Sandbox Code Playgroud)
在接收方(外部 WinForms 应用程序),我收到此消息并且可以正确读取该dwData字段:
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_COPYDATA)
{
var container = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
MessageBox.Show(container.dwData.ToString()); // 42
}
base.WndProc(ref m);
} …Run Code Online (Sandbox Code Playgroud) 一般来说,我需要能够从我在编译时不知道的任何 DLL 中调用任何非托管函数。
我看到的所有文章(例如https://blogs.msdn.microsoft.com/jonathanswift/2006/10/03/dynamically-calling-an-unmanaged-dll-from-net-c/)都建议使用委托,但我在编译时不知道我要调用哪个函数,甚至不知道它需要哪些参数和多少参数。
基本上我有一个用户输入,如:调用“Kernel32.dll”函数“DeleteFile”参数[“C:\testfile.txt”]。
你能建议至少如何谷歌吗?“动态”这个词没有帮助..
任务本身有点疯狂,因为它实际上是一个大学项目。不确定它在现实生活中是否有用..
var dll = "kernel32.dll";
var fun = "DeleteFile";
var args = new object[] { "C:\\dev\\test.txt" };
IntPtr pDll = NativeMethods.LoadLibrary(dll);
IntPtr pFun = NativeMethods.GetProcAddress(pDll, fun);
// How can I call it in a different way, without having a delegate?
Marshal.GetDelegateForFunctionPointer(pFun, typeof(?????));
Run Code Online (Sandbox Code Playgroud) 我在 C# 中为 QuickUsb 编写了一个包装类来访问非托管库。有关完整的实现,请参阅此要点。
这个问题的主要兴趣点是以下部分:
public class QuickUsbPort
{
private class SafeQuickUsbHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[DllImport("QuickUsb.dll", CharSet = CharSet.Ansi)] static extern
int QuickUsbClose(IntPtr handle);
public SafeQuickUsbHandle(IntPtr handle) : base(true)
{
SetHandle(handle);
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return QuickUsbClose(handle) != 0;
}
}
private static class NativeLib
{
[DllImport("QuickUsb.dll", CharSet = CharSet.Ansi)] static extern
int QuickUsbOpen(out SafeQuickUsbHandle handle, string deviceName);
public static SafeQuickUsbHandle Open(string deviceName)
{
if (QuickUsbOpen(out SafeQuickUsbHandle handle, deviceName) == 0)
{
throw …Run Code Online (Sandbox Code Playgroud) 我在这里引用以下线程来回答我的问题:
我基本上想做与 OP 相同的事情,但与响应此线程的其他一些用户不同,在添加代码示例中未明确定义的缺少的 PInvoke 声明后,我无法使代码正常工作。我组装了一个类文件,试图将所有内容放在一起,并引用了 PInvoke.net 的声明(我不确定这是否是用户 michalczerwinski 所做的,或者他是否正在使用某种 PInvoke 库)。这是我到目前为止所拥有的:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading.Tasks;
namespace Example
{
public static class TrayTooltip
{
[Flags]
public enum ProcessAccessFlags : uint
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation …Run Code Online (Sandbox Code Playgroud) 在 .NET Core 控制台应用程序中从 C# 调用 MacOS 的 os_log 的语法应该是什么?
基于
https://developer.apple.com/documentation/os/os_log
和
如何将 iOS OSLog 与 Xamarin 一起使用?
和
https://opensource.apple.com/source/xnu/xnu-4903.221.2/libkern/os/log.h.auto.html
我期待这样的事情:
using System.Runtime.InteropServices;
namespace Foo
{
class Program
{
[DllImport("__Internal", EntryPoint = "os_log_create")]
private static extern IntPtr os_log_create(string subsystem, string category);
[DllImport("__Internal", EntryPoint = "os_log")]
private static extern void os_log(IntPtr log, string format, string message);
static void Main(string[] args)
{
IntPtr log = os_log_create("some.bundle.id", "SomeCategory");
os_log(log, "%s", "Test!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在我的 Mac 上运行它时,我得到一个System.DllNotFoundException说Unable to …
我在 MacOS 上的 .NET Core 中有一个 (C#) 控制台应用程序。
\n\n\xc2\xa0
\n\n如何获取当前用户名?
\n\n\xc2\xa0
\n\n我试过
\n\n环境.GetEnvironmentVariable(“用户”);
\n\n和
\n\n环境.GetEnvironmentVariable(“用户名”);
\n\n但我什么也没得到。
\n\n我想getpwuid()根据此处描述的提示尝试 P/Invoke:\xc2\xa0
/sf/answers/1318942061/ \xc2\xa0
\n\n但我不确定该passwd结构的 C# 语法应该是什么。
对此表示赞赏的任何帮助,以及 P/Invoke 上资源的任何指示都可以帮助我了解 P/Invoke 从 .NET Core 到 MacOS 本机代码的诀窍。
\npinvoke ×10
c# ×9
.net ×2
.net-core ×2
macos ×2
winapi ×2
createfile ×1
dll ×1
filestream ×1
marshalling ×1
oslog ×1
process ×1
tooltip ×1
tray ×1
unmanaged ×1
vb.net ×1
winforms ×1
wm-copydata ×1