》一文中,我提到过把Flash作为控件嵌入到WinForm程序中以提高软件的互动效果并降低开发难度这样一种思路。但这样一个系统,我们往往不希望随应用程序打包,或者让用户看到,很多很多的FLASH文件。其中一个办法就是把flash文件作为资源嵌入到系统中。但这样又出现一个问题,Flash Player只有一个Movie属性用于指定当前播放的媒体,而这个字符串属性只能是本地文件或者一个URL。我们可以在运行时把资源里的flash释放到一个临时目录,但这样一来失去了打包的意义,二来无法保护flash文件。

  我们希望最好的解决方案,就是Flash Player提供类似于DataSet.ReadXml()这样的方法,既可以从指定名字的Xml文件读取数据,又可以从一个数据流(Stream)读数据。但是找遍了Flash Player的所有参数,似乎只有MovieData这个属性有点接近,如果我们能直接把Flash文件的内容赋值给它就好了。不过目前我还没有找到关于这个属性的资料 -_-

  另外一个思路,就是在我们的程序运行的时候,动态建立一个自己的http服务器,可以直接从资源中读取内容。事实上,对于大部分要求文件或url形式的内容,都可以通过建立虚拟http服务器来模拟。但实现起来要费点功夫,而且http会在本机留下缓存,安全性不高。

  最后在
》一文找到了另外一种方法,就是通过命名管道(Named Pipe)。
首先我们看看命名管道为什么能够解决这个问题。这要从它的运行机制讲起。当一个命名管道被建立起来后,它的服务端和客户端之间的数据交流,就完全是通过和操作文件一样的方式来进行,即CreateFile(),ReadFile()和WriteFile()三个函数。也就是说客户端可以像读取文件一样,来读取管道里的数据。

  我们通过调用Win32 API 既可创建管道。这里先简单讲一下服务器端的处理流程:
  1、通过CreateNamedPipe()函数创建一个命名管道,如果成功,会返回这个管道实例的句柄。
  2、管道创建成功后,调用ConnectNamedPipe()函数等到客户端连接。
  3、如果有客户端连接进来,可以通过对文件的操作来交换数据,例如ReadFile()和WriteFile()。
  在.NET里我们不必用这些Win32 API函数来读写文件,直接用System.IO命名空间下的类即可(将文件读写的内存指针指向管道句柄即可)。

  注:目前该方法只针对在Flash Player播放器打开
\\.\pipe\testPipe 才有效。如果您使用的是Flash Player 7.0,那么一定要用 \\?\pipe\testPipe才行。
  至于在html页面或WinForm里的Flash Player控件,指定其Movie属性为"\\.\pipe\testPipe",目前尚无效。

  以下是简单的例子:

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件using System;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
using System.IO;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
{
{

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
/// 应用程序的主入口点。
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
/// </summary>
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [STAThread]
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            CreatePipe();
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
private const int BUFFER_SIZE = 1024;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
private const int PIPE_TIMEOUT = 1000;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
private const string PIPE_NAME = @"\\.\pipe\testPipe";
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            API.SECURITY_ATTRIBUTES sec 
= new API.SECURITY_ATTRIBUTES();
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int pipeHandle = API.CreateNamedPipe( PIPE_NAME, API.PIPE_ACCESS_DUPLEX
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                , API.PIPE_WAIT, API.PIPE_UNLIMITED_INSTANCES, BUFFER_SIZE, BUFFER_SIZE
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                , PIPE_TIMEOUT, 
ref sec);
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            Console.WriteLine(pipeHandle);
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                Console.WriteLine(
"Cannot create pipe.");
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                
return;
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                Console.WriteLine(
"Create pipe successful. Waiting for connection利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件");
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            API.OVERLAPPED lapped 
= new API.OVERLAPPED();
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int connected = API.ConnectNamedPipe( pipeHandle, ref lapped );
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                
// 如果从资源文件读入swf文件,用下面这句
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                
// using ( Stream swf = typeof(API).Assembly.GetManifestResourceStream("PipeServer.test.swf")) {
{
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                        
int reads;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                        
byte[] buffer = new byte[BUFFER_SIZE];
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                            pipe.Write(buffer, 
0, reads);
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                        }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                        pipe.Flush();
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                    }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                Console.WriteLine(
"Someone arrived.");
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                API.DisconnectNamedPipe(pipeHandle);
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                API.CloseHandle( pipeHandle );
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件                API.CloseHandle( pipeHandle );
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件    }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件}

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件using System;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
using System.Runtime.InteropServices;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public const int INVALID_HANDLE_VALUE = -1;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public const int PIPE_ACCESS_INBOUND = 0x1;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public const int PIPE_ACCESS_OUTBOUND = 0x2;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public const int PIPE_ACCESS_DUPLEX = 0x3;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public const int PIPE_WAIT = 0x0;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public const int PIPE_UNLIMITED_INSTANCES = 255;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [DllImport(
"kernel32.dll", EntryPoint="CreateNamedPipe")]
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public static extern int CreateNamedPipe (
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
string lpName,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int dwOpenMode,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int dwPipeMode,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int nMaxInstances,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int nOutBufferSize,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int nInBufferSize,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int nDefaultTimeOut,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
ref SECURITY_ATTRIBUTES lpSecurityAttributes
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        );
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [StructLayout(LayoutKind.Sequential)]
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int nLength;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int lpSecurityDescriptor;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int bInheritHandle;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [DllImport(
"kernel32.dll", EntryPoint="ConnectNamedPipe")]
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public static extern int ConnectNamedPipe (
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int hNamedPipe,
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
ref OVERLAPPED lpOverlapped
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        );
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [StructLayout(LayoutKind.Sequential)]
{
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int Internal;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int InternalHigh;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int offset;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int OffsetHigh;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
public int hEvent;
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [DllImport(
"kernel32.dll", EntryPoint="CloseHandle")]
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public static extern int CloseHandle (
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int hObject
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        );
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        [DllImport(
"kernel32.dll", EntryPoint="DisconnectNamedPipe")]
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        
public static extern int DisconnectNamedPipe (
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件            
int hNamedPipe
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件        );
利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件    }

利用命名管道(Named Pipe)向Flash Player模拟Flash媒体文件}

相关文章:

  • 2021-09-05
  • 2021-12-19
  • 2021-09-01
  • 2022-12-23
  • 2022-12-23
  • 2021-12-05
  • 2021-10-31
  • 2022-02-13
猜你喜欢
  • 2022-01-03
  • 2022-03-08
  • 2022-12-23
  • 2021-07-25
  • 2022-12-23
  • 2021-10-08
  • 2022-12-23
相关资源
相似解决方案