浏览器网页如何直接访问客户端电脑文件?
1、创建C#类库项目:ImageActiveX
使用VS开发工具新建 C# .net framework 类库->选择.net framework 4.6->项目取名“ImageActiveX”;
2、ImageActiveX项目右击应用程序->属性->应用程序->程序集信息->然后选中“使程序集COM可见”
3、ImageActiveX项目右击应用程序->属性->生成->然后选中“为COM互操作注册”
4、ImageActiveX项目新建类Main.class 代码如下:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace ImageActiveX
{
[ComImport, GuidAttribute("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
[PreserveSig]
int GetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] ref int pdwSupportedOptions, [MarshalAs(UnmanagedType.U4)] ref int pdwEnabledOptions);
[PreserveSig()]
int SetInterfaceSafetyOptions(ref Guid riid, [MarshalAs(UnmanagedType.U4)] int dwOptionSetMask, [MarshalAs(UnmanagedType.U4)] int dwEnabledOptions);
}
[Guid("E52C3E70-B486-4743-B8AE-5D830A561442")]
public partial class Main : IObjectSafety
{
private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
private const int S_OK = 0;
private const int E_FAIL = unchecked((int)0x80004005);
private const int E_NOINTERFACE = unchecked((int)0x80004002);
private bool _fSafeForScripting = true;
private bool _fSafeForInitializing = true;
public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
{
int Rslt = E_FAIL;
string strGUID = riid.ToString("B");
pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
switch (strGUID)
{
case _IID_IDispatch:
case _IID_IDispatchEx:
Rslt = S_OK;
pdwEnabledOptions = 0;
if (_fSafeForScripting == true)
pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
break;
case _IID_IPersistStorage:
case _IID_IPersistStream:
case _IID_IPersistPropertyBag:
Rslt = S_OK;
pdwEnabledOptions = 0;
if (_fSafeForInitializing == true)
pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
break;
default:
Rslt = E_NOINTERFACE;
break;
}
return Rslt;
}
public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
{
int Rslt = E_FAIL;
string strGUID = riid.ToString("B");
switch (strGUID)
{
case _IID_IDispatch:
case _IID_IDispatchEx:
if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
Rslt = S_OK;
break;
case _IID_IPersistStorage:
case _IID_IPersistStream:
case _IID_IPersistPropertyBag:
if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
Rslt = S_OK;
break;
default:
Rslt = E_NOINTERFACE;
break;
}
return Rslt;
}
}
public partial class Main
{
public string SayHello()
{
return "Hi I'm from ActiveX Compliled by C#!";
}
public string SetData(string input)
{
return input;
}
public string Image_GetBase64(string imagePath)
{
if (string.IsNullOrWhiteSpace(imagePath))
{
return "出错了:你传入参数为空!";
}
if (!File.Exists(imagePath))
{
return "出错了:你传入的图片文件不存在!";
}
try
{
Bitmap tmpBitmap = new Bitmap(imagePath);
string tmpBase64 = "";
using (MemoryStream ms = new MemoryStream())
{
tmpBitmap.Save(ms, ImageFormat.Jpeg);
byte[] tmpByteData = new byte[ms.Length];
ms.Position = 0;
ms.Read(tmpByteData, 0, (int)ms.Length);
ms.Close();
tmpBase64 = Convert.ToBase64String(tmpByteData);
}
return tmpBase64;
}
catch (Exception ex)
{
return string.Format("出错了,读取图片转base64异常:{0}", ex.Message);
}
}
/// <summary>
/// 将Base64的图片保存到指定位置
/// <returns></returns>
public bool Image_SaveToLocal(string imgBase64,string img_SavePath)
{
//自己添加自己的方法
return true;
}
}
}
5、创建插件安装程序:ImageActiveXSetUp
VS新建项目选择:“SetUp Project” 或者 “安装项目”;
本项目不需要写任何代码 只是做安装配置即可;
可选择项目 按F4 进行具体的安装配置设置;
6、如果没有 “SetUp Project” 或者 “安装项目”这个两个选项,需要手动安装扩展插件:VS菜单->扩展->管理扩展->搜索安装:Microsoft Visual Studio Installer Projects
7、ImageActiveXSetUp项目右键->添加(Add)->项目输出->项目:选择ImageActiveX插件项目
8、编译程序打包项目(ImageActiveXSetUp):
生成Setup.exe文件和ImageActiveXSetUp.msi安装文件;
9、在本地双击运行Setup.exe文件 安装插件:
10、用IE浏览器打开网页(MyActiveXTest.html)测试插件功能,可放在本地桌面测试,也可以将网页放到服务器上通过客户端访问页面测试:
具体代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
//插件安装成功之后,就可以使用这种方式进行检测
function SayHello() {
try {
//实例化插件
var test = new ActiveXObject("ImageActiveX.Main");
if (test == undefined)
{ alert("初始化失败"); }
else
{ alert(test.SayHello()); }
}
catch (e) {
console.log(e);
}
}
function SetData() {
try {
var test = new ActiveXObject("ImageActiveX.Main");
if (test == undefined)
{ alert("初始化失败"); }
else
{ alert(test.SetData("这是浏览器输入原样返回")); }
}
catch (e) {
console.log(e);
}
}
//从客户端系统直接获取图片的Base64编码
function LoadImg() {
try {
var test = new ActiveXObject("ImageActiveX.Main");
if (test == undefined)
{ alert("初始化失败"); }
else
{
let tmpPath=document.getElementById('001').value;
let tmpBase64=test.Image_GetBase64(tmpPath);
document.getElementById('showBase64Img').src='data:image/png;base64,' + tmpBase64;
}
}
catch (e) {
console.log(e);
}
}
</script>
</head>
<body>
<!--引用插件:浏览器会根据ClassID检测对应插件是否已经注册,没有注册提示下载指定网路路径的setup.exe文件;由于本插件没有UI 所以width height都设置为0即可-->
<object cla---ssid="CLSID:E52C3E70-B486-4743-B8AE-5D830A561443" codebase="setup.exe" id="abc
<input type="button" value="调用SayHello()" onclick="SayHello()" />
<input type="button" value="调用SetData(str msg)" onclick="SetData()" />
<br/>
<br/>
输入客户端本地图片路径:
<input id="001" type="text" value="D:\\duoduo.png" ></input>
<input type="button" value="加载客户端电脑文件测试" onclick="LoadImg()" />
<br/>
<br/>
<!--展示最终从客户端本地加载的图片-->
<img id='showBase64Img' src='' width="762px" height="702px" />
</body>
</html>
11、最终测试效果如下图: