Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这个PInvoke代码正确可靠吗?_C#_.net_.net 4.0_Pinvoke_Alternate Data Stream - Fatal编程技术网

C# 这个PInvoke代码正确可靠吗?

C# 这个PInvoke代码正确可靠吗?,c#,.net,.net-4.0,pinvoke,alternate-data-stream,C#,.net,.net 4.0,Pinvoke,Alternate Data Stream,在中,我搜索了一个简单的解决方案来解除阻止文件。 感谢所有的评论和回答,我通过PInvokingDeleteFile找到了一个简单的解决方案 它可以工作,但因为我从未通过PInvoke(Win32)使用过文件操作,我不知道是否存在一些缺陷,或者是否有另一种方法调用DeleteFile来删除文件的备用流 我也不知道我是否必须用try/catch来包装调用,或者仅仅查看布尔结果就足够了。在我的测试中,没有出现异常,但我不知道现实世界会发生什么 public class FileUnblocker {

在中,我搜索了一个简单的解决方案来解除阻止文件。 感谢所有的评论和回答,我通过PInvoking
DeleteFile
找到了一个简单的解决方案

它可以工作,但因为我从未通过PInvoke(Win32)使用过文件操作,我不知道是否存在一些缺陷,或者是否有另一种方法调用
DeleteFile
来删除文件的备用流

我也不知道我是否必须用try/catch来包装调用,或者仅仅查看布尔结果就足够了。在我的测试中,没有出现异常,但我不知道现实世界会发生什么

public class FileUnblocker {

    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DeleteFile(string name );

    public bool Unblock(string fileName) {
        return DeleteFile(fileName+ ":Zone.Identifier");
    }
}
这个代码看起来可靠吗

更新

我发布了一个不完整的方法(unblock方法没有将“Zone.Identifier”文本连接到文件名)。对不起,我现在已经更正了。调用本机方法永远不会引发异常。如果文件删除失败,无论出于何种原因,对
DeleteFile
的调用将返回false

您的p/Invoke代码很好。您正确地使用了Unicode字符,将
SetLastError
设置为
true
,并且参数编组正确。要检查错误,请从
DeleteFile
中查找布尔返回值。如果为false(即调用失败),则调用查找Win32错误代码

功能失效的最明显原因是:

  • 该文件不存在
  • 备用流不存在
  • 进程没有足够的权限删除备用流

  • 对于1和2,将返回错误代码。对于3,您将得到一个错误代码。

    我对代码做了一些改进。现在,您可以将启动路径传递给UnblockPath()函数,它将自动解除对可执行文件的所有文件和子目录文件的阻止。它可以进一步细化,只搜索.exe、.dll等

    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DeleteFile(string name);
    
    public static void UnblockPath(string path)
    {
        string[] files = System.IO.Directory.GetFiles(path);
        string[] dirs = System.IO.Directory.GetDirectories(path);
    
        foreach (string file in files)
        {
            UnblockFile(file);
        }
    
        foreach (string dir in dirs)
        {
            UnblockPath(dir);
        }
    
    }
    
    public static bool UnblockFile(string fileName)
    {
        return DeleteFile(fileName + ":Zone.Identifier");
    }
    

    对于那些通过并盲目否决答案的人:请有礼貌地解释为什么答案是错误的。@克里斯,实际上我想知道的是,是谁否决了两个答案:1)只不过是给了问题中的答案同等的P/Invoke签名,在一个例子中,使用Ansi字符串和2)并没有以任何方式解决这个问题。我做到了,你永远也不会明白我的意思。哈哈哈。>:)StackOverflow不是代码审阅站点。CodeReview.SE是。@SamAxe Code Review不是一个审查代码可靠性的网站。StackOverflow是。+1抱歉,我太匆忙了,没有发布代码,我忘记了在Unblock方法中添加流标识符。我已经编辑了我的帖子。对不起,一般来说,我尽量不发布糟糕的问题,浪费人们的时间。下次我会更加小心。@HCL是的,我有点被甩了。不过,我想我现在已经涵盖了所有的基础!这与此相反-锁定文件。这与问题无关,但仍然有用,谢谢。
    using System;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    
    internal class Zone
    {
        public static void WriteAlternateStream(string path, string text)
        {
            const int GENERIC_WRITE = 1073741824;
            const int FILE_SHARE_WRITE = 2;
            const int OPEN_ALWAYS = 4;
            var stream = CreateFileW(path, GENERIC_WRITE, FILE_SHARE_WRITE, IntPtr.Zero, OPEN_ALWAYS, 0, IntPtr.Zero);
            using (FileStream fs = new FileStream(stream, FileAccess.Write))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(text);
                }
            }
        }
        public static void Id()
        {
            var x = Application.ExecutablePath + ":Zone.Identifier";
            WriteAlternateStream(x, "[ZoneTransfer]\r\nZoneId=3");
        }
        # region Imports
        [DllImport("kernel32.dll", EntryPoint = "CreateFileW")]
        public static extern System.IntPtr CreateFileW(
            [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            [InAttribute()] IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            [InAttribute()] IntPtr hTemplateFile
        );
        #endregion
    }